summaryrefslogtreecommitdiffstats
path: root/src/vlib/stats/stats.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vlib/stats/stats.c')
-rw-r--r--src/vlib/stats/stats.c259
1 files changed, 154 insertions, 105 deletions
diff --git a/src/vlib/stats/stats.c b/src/vlib/stats/stats.c
index 97f84006eaf..75c3986f3b9 100644
--- a/src/vlib/stats/stats.c
+++ b/src/vlib/stats/stats.c
@@ -135,6 +135,7 @@ vlib_stats_remove_entry (u32 entry_index)
vlib_stats_entry_t *e = vlib_stats_get_entry (sm, entry_index);
void *oldheap;
counter_t **c;
+ vlib_counter_t **vc;
u32 i;
if (entry_index >= vec_len (sm->directory_vector))
@@ -142,6 +143,8 @@ vlib_stats_remove_entry (u32 entry_index)
oldheap = clib_mem_set_heap (sm->heap);
+ vlib_stats_segment_lock ();
+
switch (e->type)
{
case STAT_DIR_TYPE_NAME_VECTOR:
@@ -158,6 +161,14 @@ vlib_stats_remove_entry (u32 entry_index)
vec_free (c);
break;
+ case STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED:
+ vc = e->data;
+ e->data = 0;
+ for (i = 0; i < vec_len (vc); i++)
+ vec_free (vc[i]);
+ vec_free (vc);
+ break;
+
case STAT_DIR_TYPE_SCALAR_INDEX:
case STAT_DIR_TYPE_SYMLINK:
break;
@@ -165,6 +176,8 @@ vlib_stats_remove_entry (u32 entry_index)
ASSERT (0);
}
+ vlib_stats_segment_unlock ();
+
clib_mem_set_heap (oldheap);
hash_unset_str_key_free (&sm->directory_vector_by_name, e->name);
@@ -187,44 +200,47 @@ vlib_stats_set_entry_name (vlib_stats_entry_t *e, char *s)
s[i] = 0;
}
-void
-vlib_stats_update_counter (void *cm_arg, u32 cindex,
- stat_directory_type_t type)
+static u32
+vlib_stats_new_entry_internal (stat_directory_type_t t, u8 *name)
{
- vlib_simple_counter_main_t *cm = (vlib_simple_counter_main_t *) cm_arg;
vlib_stats_segment_t *sm = vlib_stats_get_segment ();
vlib_stats_shared_header_t *shared_header = sm->shared_header;
- char *stat_segment_name;
- vlib_stats_entry_t e = { 0 };
-
- /* Not all counters have names / hash-table entries */
- if (!cm->name && !cm->stat_segment_name)
- return;
+ vlib_stats_entry_t e = { .type = t };
ASSERT (shared_header);
- vlib_stats_segment_lock ();
-
- /* Lookup hash-table is on the main heap */
- stat_segment_name = cm->stat_segment_name ? cm->stat_segment_name : cm->name;
-
- u32 vector_index = vlib_stats_find_entry_index ("%s", stat_segment_name);
-
- /* Update the vector */
- if (vector_index == STAT_SEGMENT_INDEX_INVALID)
+ u32 vector_index = vlib_stats_find_entry_index ("%v", name);
+ if (vector_index != STAT_SEGMENT_INDEX_INVALID) /* Already registered */
{
- vlib_stats_set_entry_name (&e, stat_segment_name);
- e.type = type;
- vector_index = vlib_stats_create_counter (&e);
+ vector_index = ~0;
+ goto done;
}
- vlib_stats_entry_t *ep = &sm->directory_vector[vector_index];
- ep->data = cm->counters;
+ vec_add1 (name, 0);
+ vlib_stats_set_entry_name (&e, (char *) name);
+
+ vlib_stats_segment_lock ();
+ vector_index = vlib_stats_create_counter (&e);
- /* Reset the client hash table pointer, since it WILL change! */
shared_header->directory_vector = sm->directory_vector;
vlib_stats_segment_unlock ();
+
+done:
+ vec_free (name);
+ return vector_index;
+}
+
+u32
+vlib_stats_add_gauge (char *fmt, ...)
+{
+ va_list va;
+ u8 *name;
+
+ va_start (va, fmt);
+ name = va_format (0, fmt, &va);
+ va_end (va);
+ return vlib_stats_new_entry_internal (STAT_DIR_TYPE_SCALAR_INDEX, name);
}
void
@@ -286,77 +302,6 @@ vlib_stats_update_error_vector (u64 *error_vector, u32 thread_index, int lock)
}
void
-vlib_stats_delete_cm (void *cm_arg)
-{
- vlib_simple_counter_main_t *cm = (vlib_simple_counter_main_t *) cm_arg;
- vlib_stats_segment_t *sm = vlib_stats_get_segment ();
- vlib_stats_entry_t *e;
-
- /* Not all counters have names / hash-table entries */
- if (!cm->name && !cm->stat_segment_name)
- return;
-
- vlib_stats_segment_lock ();
-
- /* Lookup hash-table is on the main heap */
- char *stat_segment_name =
- cm->stat_segment_name ? cm->stat_segment_name : cm->name;
- u32 index = vlib_stats_find_entry_index ("%s", stat_segment_name);
-
- e = &sm->directory_vector[index];
-
- hash_unset_str_key_free (&sm->directory_vector_by_name, e->name);
-
- memset (e, 0, sizeof (*e));
- e->type = STAT_DIR_TYPE_EMPTY;
-
- vlib_stats_segment_unlock ();
-}
-
-static u32
-vlib_stats_new_entry_internal (stat_directory_type_t t, u8 *name)
-{
- vlib_stats_segment_t *sm = vlib_stats_get_segment ();
- vlib_stats_shared_header_t *shared_header = sm->shared_header;
- vlib_stats_entry_t e = { .type = t };
-
- ASSERT (shared_header);
-
- u32 vector_index = vlib_stats_find_entry_index ("%v", name);
- if (vector_index != STAT_SEGMENT_INDEX_INVALID) /* Already registered */
- {
- vector_index = ~0;
- goto done;
- }
-
- vec_add1 (name, 0);
- vlib_stats_set_entry_name (&e, (char *) name);
-
- vlib_stats_segment_lock ();
- vector_index = vlib_stats_create_counter (&e);
-
- shared_header->directory_vector = sm->directory_vector;
-
- vlib_stats_segment_unlock ();
-
-done:
- vec_free (name);
- return vector_index;
-}
-
-u32
-vlib_stats_add_gauge (char *fmt, ...)
-{
- va_list va;
- u8 *name;
-
- va_start (va, fmt);
- name = va_format (0, fmt, &va);
- va_end (va);
- return vlib_stats_new_entry_internal (STAT_DIR_TYPE_SCALAR_INDEX, name);
-}
-
-void
vlib_stats_set_gauge (u32 index, u64 value)
{
vlib_stats_segment_t *sm = vlib_stats_get_segment ();
@@ -435,26 +380,130 @@ vlib_stats_add_counter_vector (char *fmt, ...)
name);
}
+u32
+vlib_stats_add_counter_pair_vector (char *fmt, ...)
+{
+ va_list va;
+ u8 *name;
+
+ va_start (va, fmt);
+ name = va_format (0, fmt, &va);
+ va_end (va);
+ return vlib_stats_new_entry_internal (STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED,
+ name);
+}
+
+static int
+vlib_stats_validate_will_expand_internal (u32 entry_index, va_list *va)
+{
+ vlib_stats_segment_t *sm = vlib_stats_get_segment ();
+ vlib_stats_entry_t *e = vlib_stats_get_entry (sm, entry_index);
+ void *oldheap;
+ int rv = 1;
+
+ oldheap = clib_mem_set_heap (sm->heap);
+ if (e->type == STAT_DIR_TYPE_COUNTER_VECTOR_SIMPLE)
+ {
+ u32 idx0 = va_arg (*va, u32);
+ u32 idx1 = va_arg (*va, u32);
+ u64 **data = e->data;
+
+ if (idx0 >= vec_max_len (data))
+ goto done;
+
+ for (u32 i = 0; i <= idx0; i++)
+ if (idx1 >= vec_max_len (data[idx0]))
+ goto done;
+ }
+ else if (e->type == STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED)
+ {
+ u32 idx0 = va_arg (*va, u32);
+ u32 idx1 = va_arg (*va, u32);
+ vlib_counter_t **data = e->data;
+
+ va_end (*va);
+
+ if (idx0 >= vec_max_len (data))
+ goto done;
+
+ for (u32 i = 0; i <= idx0; i++)
+ if (idx1 >= vec_max_len (data[idx0]))
+ goto done;
+ }
+ else
+ ASSERT (0);
+
+ rv = 0;
+done:
+ clib_mem_set_heap (oldheap);
+ return rv;
+}
+
+int
+vlib_stats_validate_will_expand (u32 entry_index, ...)
+{
+ va_list va;
+ int rv;
+
+ va_start (va, entry_index);
+ rv = vlib_stats_validate_will_expand_internal (entry_index, &va);
+ va_end (va);
+ return rv;
+}
+
void
-vlib_stats_validate_counter_vector (u32 entry_index, u32 vector_index)
+vlib_stats_validate (u32 entry_index, ...)
{
vlib_stats_segment_t *sm = vlib_stats_get_segment ();
vlib_stats_entry_t *e = vlib_stats_get_entry (sm, entry_index);
void *oldheap;
- counter_t **c = e->data;
+ va_list va;
+ int will_expand;
- if (vec_len (c) > 0 && vec_len (c[0]) > vector_index)
- return;
+ va_start (va, entry_index);
+ will_expand = vlib_stats_validate_will_expand_internal (entry_index, &va);
+ va_end (va);
+
+ if (will_expand)
+ vlib_stats_segment_lock ();
oldheap = clib_mem_set_heap (sm->heap);
- vlib_stats_segment_lock ();
- vec_validate_aligned (c, 0, CLIB_CACHE_LINE_BYTES);
- vec_validate_aligned (c[0], vector_index, CLIB_CACHE_LINE_BYTES);
- e->data = c;
+ va_start (va, entry_index);
+
+ if (e->type == STAT_DIR_TYPE_COUNTER_VECTOR_SIMPLE)
+ {
+ u32 idx0 = va_arg (va, u32);
+ u32 idx1 = va_arg (va, u32);
+ u64 **data = e->data;
+
+ vec_validate_aligned (data, idx0, CLIB_CACHE_LINE_BYTES);
+
+ for (u32 i = 0; i <= idx0; i++)
+ vec_validate_aligned (data[i], idx1, CLIB_CACHE_LINE_BYTES);
+ e->data = data;
+ }
+ else if (e->type == STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED)
+ {
+ u32 idx0 = va_arg (va, u32);
+ u32 idx1 = va_arg (va, u32);
+ vlib_counter_t **data = e->data;
+
+ vec_validate_aligned (data, idx0, CLIB_CACHE_LINE_BYTES);
+
+ for (u32 i = 0; i <= idx0; i++)
+ vec_validate_aligned (data[i], idx1, CLIB_CACHE_LINE_BYTES);
+ e->data = data;
+ }
+ else
+ ASSERT (0);
+
+ va_end (va);
- vlib_stats_segment_unlock ();
clib_mem_set_heap (oldheap);
+
+ if (will_expand)
+ vlib_stats_segment_unlock ();
}
u32