summaryrefslogtreecommitdiff
path: root/service/src/sc_metrics.c
blob: b07de7a505892c92133998eb1beb17264a62d90c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
#include <rte_memcpy.h>

#include <sc_metrics.h>

/**
 * @brief Round up a value to the nearest multiple of 8.
 * Note: This function is not thread-safe.
 *
 * @param value The value to round up.
 * @return The rounded up value.
 */
uint16_t round_up_to_multiple_of_8(uint16_t value)
{
    return (value + 7) & ~7;
}

/**
 * @brief Create and initialize a new SC metrics handle.
 *
 * This function allocates and initializes a new SC metrics handle with the
 * specified capacity. It ensures that the capacity is rounded up to the
 * nearest multiple of 8. The handle includes memory for storing metrics
 * values based on the rounded capacity.
 *
 * @param capacity The number of metrics values that the handle should be able
 *                 to store. This value is rounded up to the nearest multiple
 *                 of 8.
 *
 * @return Pointer to the newly created SC metrics handle, or NULL if memory
 *         allocation fails or if an invalid capacity is provided (0).
 */
struct sc_metrics_handle * sc_metrics_handle_create(uint16_t capacity)
{
    if (capacity == 0)
    {
        MR_ERROR("Error allocating stats handle: invalid input parameters.");
        return NULL;
    }
    else if (capacity > SC_METRICS_MAX_CAPACITY)
    {
        MR_ERROR("Error allocating stats handle: capacity exceeds maximum limit.");
        return NULL;
    }

    struct sc_metrics_handle * metrics_handle = (struct sc_metrics_handle *)ZMALLOC(sizeof(struct sc_metrics_handle));
    MR_VERIFY_MALLOC(metrics_handle);

    metrics_handle->capacity = round_up_to_multiple_of_8(capacity);

    metrics_handle->values = (volatile uint64_t *)ZMALLOC(sizeof(uint64_t) * metrics_handle->capacity);
    MR_VERIFY_MALLOC(metrics_handle->values);

    return metrics_handle;
}

/**
 * @brief Delete and free an SC metrics handle.
 *
 * This function deallocates the memory associated with an SC metrics handle,
 * including its values array. After freeing the memory, it sets the pointers
 * to NULL to avoid dangling pointers.
 *
 * @param metrics_handle Pointer to the SC metrics handle to be deleted.
 *                       If this pointer is NULL, no action is taken.
 *
 * @return Return value indicating success or failure:
 *         - RT_SUCCESS (0) if the handle is successfully deleted.
 *         - RT_ERR (-1) if the handle is NULL and cannot be deleted.
 */
int sc_metrics_handle_delete(struct sc_metrics_handle * metrics_handle)
{
    if (metrics_handle == NULL)
    {
        MR_ERROR("Error deleting stats handle: invalid input parameters.");
        return RT_ERR;
    }

    FREE((void *)metrics_handle->values);
    metrics_handle->values = NULL;

    FREE((void *)metrics_handle);

    return RT_SUCCESS;
}

/**
 * @brief Set the values for the SC metrics handle.
 *
 * This function copies an array of metric values into the SC metrics handle.
 * It ensures that the provided capacity does not exceed the handle's allocated
 * capacity. The function uses `rte_memcpy` to perform the copy operation.
 *
 * @param metrics_handle Pointer to the SC metrics handle where the values will
 *                       be set. This handle must be valid and initialized.
 * @param stats Array of metric values to be copied into the handle.
 * @param capacity Number of metric values to copy from the `stats` array.
 *                 This should not exceed the handle's allocated capacity.
 *
 * @return Return value indicating success:
 *         - RT_SUCCESS (0) if the values are successfully copied.
 */
int sc_metrics_values_set(struct sc_metrics_handle * metrics_handle, uint64_t values[], uint16_t capacity)
{
    assert(metrics_handle != NULL);
    assert(metrics_handle->values != NULL);
    assert(capacity <= metrics_handle->capacity);

    rte_memcpy((void *)metrics_handle->values, values, sizeof(uint64_t) * capacity);
    return RT_SUCCESS;
}

/**
 * @brief Get the values from the SC metrics handle.
 *
 * This function copies the metric values from the SC metrics handle into the
 * provided array. It ensures that the provided capacity does not exceed the
 * handle's allocated capacity. The function uses `rte_memcpy` to perform the
 * copy operation.
 *
 * @param metrics_handle Pointer to the SC metrics handle from which the values
 *                       will be retrieved. This handle must be valid and initialized.
 * @param values Array where the metric values will be copied.
 * @param capacity Number of metric values to copy into the `values` array.
 *                 This should not exceed the handle's allocated capacity.
 *
 * @return Return value indicating success:
 *         - RT_SUCCESS (0) if the values are successfully copied.
 */
int sc_metrics_values_get(struct sc_metrics_handle * metrics_handle, uint64_t values[], uint16_t capacity)
{
    assert(metrics_handle != NULL);
    assert(metrics_handle->values != NULL);
    assert(capacity <= metrics_handle->capacity);

    rte_memcpy(values, (void *)metrics_handle->values, sizeof(uint64_t) * capacity);
    return RT_SUCCESS;
}

/**
 * @brief Get a single value from the SC metrics handle.
 *
 * This function retrieves a single metric value from the SC metrics handle at
 * the specified key. The function ensures that the key is within the handle's
 * allocated capacity. The value is directly read from the handle's values array
 * at the specified key.
 *
 * @param metrics_handle Pointer to the SC metrics handle from which the value
 *                       will be retrieved. This handle must be valid and initialized.
 * @param value Pointer to the variable where the metric value will be stored.
 * @param key The key from which to retrieve the metric value. This key must be
 *            within the handle's allocated capacity.
 *
 * @return Return value indicating success:
 *         - RT_SUCCESS (0) if the value is successfully retrieved.
 */
int sc_metrics_value_get(struct sc_metrics_handle * metrics_handle, uint64_t * value, uint16_t key)
{
    assert(value != NULL);
    assert(metrics_handle != NULL);
    assert(metrics_handle->values != NULL);
    assert(key < metrics_handle->capacity);

    *value = metrics_handle->values[key];
    return RT_SUCCESS;
}

/**
 * @brief Reset all values in the SC metrics handle to zero.
 *
 * This function sets all values in the SC metrics handle to zero. It uses
 * `memset` to overwrite the entire allocated space for metric values with zeros.
 * This operation effectively resets the metrics handle to its initial state.
 *
 * @param metrics_handle Pointer to the SC metrics handle to be reset.
 *                       This handle must be valid and initialized.
 *
 * @return Return value indicating success:
 *         - RT_SUCCESS (0) if the values are successfully reset.
 */
int sc_metrics_values_reset(struct sc_metrics_handle * metrics_handle)
{
    assert(metrics_handle != NULL);
    assert(metrics_handle->values != NULL);

    memset((void *)metrics_handle->values, 0, sizeof(uint64_t) * metrics_handle->capacity);
    return RT_SUCCESS;
}

/**
 * @brief Accumulate values into the SC metrics handle.
 *
 * This function adds values from the `inc_values` array to the existing values
 * in the SC metrics handle. The accumulation is performed element-wise for
 * the specified `capacity`. The function ensures that the provided capacity
 * does not exceed the handle's allocated capacity.
 *
 * @param metrics_handle Pointer to the SC metrics handle where the values
 *                       will be accumulated. This handle must be valid and
 *                       initialized.
 * @param inc_values Array of values to be added to the current values in
 *                   the handle.
 * @param capacity Number of values to accumulate. This should not exceed
 *                 the handle's allocated capacity.
 *
 * @return Return value indicating success:
 *         - RT_SUCCESS (0) if the values are successfully accumulated.
 */
int sc_metrics_accumulate(struct sc_metrics_handle * metrics_handle, uint64_t inc_values[], uint16_t capacity)
{
    assert(metrics_handle != NULL);
    assert(metrics_handle->values != NULL);
    assert(capacity <= metrics_handle->capacity);

    volatile uint64_t * values = metrics_handle->values;

    for (uint16_t i = 0; i < capacity; i++)
    {
        values[i] += inc_values[i];
    }

    return RT_SUCCESS;
}