X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvpp%2Fstats%2Fstat_segment.c;h=b96e667783a58368dc71b5e80da38ad2e196b6cc;hb=72e31bc2d9b910147c09e1c329713fccc873a018;hp=f4758a7cdb58b40f9359139a5191f6d432ae41ca;hpb=a488f37559493657b59181c1212e57b3b9cc3689;p=vpp.git diff --git a/src/vpp/stats/stat_segment.c b/src/vpp/stats/stat_segment.c index f4758a7cdb5..b96e667783a 100644 --- a/src/vpp/stats/stat_segment.c +++ b/src/vpp/stats/stat_segment.c @@ -60,24 +60,17 @@ vlib_stats_push_heap (void *old) } static u32 -lookup_or_create_hash_index (u8 * name, u32 next_vector_index) +lookup_hash_index (u8 * name) { stat_segment_main_t *sm = &stat_segment_main; - u32 index; + u32 index = STAT_SEGMENT_INDEX_INVALID; hash_pair_t *hp; /* Must be called in the context of the main heap */ ASSERT (clib_mem_get_heap () != sm->heap); hp = hash_get_pair (sm->directory_vector_by_name, name); - if (!hp) - { - /* we allocate our private copy of 'name' */ - hash_set (sm->directory_vector_by_name, format (0, "%s%c", name, 0), - next_vector_index); - index = next_vector_index; - } - else + if (hp) { index = hp->value[0]; } @@ -85,6 +78,76 @@ lookup_or_create_hash_index (u8 * name, u32 next_vector_index) return index; } +static void +create_hash_index (u8 * name, u32 index) +{ + stat_segment_main_t *sm = &stat_segment_main; + + /* Must be called in the context of the main heap */ + ASSERT (clib_mem_get_heap () != sm->heap); + + hash_set (sm->directory_vector_by_name, format (0, "%s%c", name, 0), index); +} + +static u32 +vlib_stats_get_next_vector_index () +{ + stat_segment_main_t *sm = &stat_segment_main; + u32 next_vector_index = vec_len (sm->directory_vector); + + ssize_t i; + vec_foreach_index_backwards (i, sm->directory_vector) + { + if (sm->directory_vector[i].type == STAT_DIR_TYPE_EMPTY) + { + next_vector_index = i; + break; + } + } + + return next_vector_index; +} + +static u32 +vlib_stats_create_counter (stat_segment_directory_entry_t * e, void *oldheap) +{ + stat_segment_main_t *sm = &stat_segment_main; + + ASSERT (clib_mem_get_heap () == sm->heap); + + u32 index = vlib_stats_get_next_vector_index (); + + clib_mem_set_heap (oldheap); + create_hash_index ((u8 *) e->name, index); + clib_mem_set_heap (sm->heap); + + vec_validate (sm->directory_vector, index); + sm->directory_vector[index] = *e; + + return index; +} + +static void +vlib_stats_delete_counter (u32 index, void *oldheap) +{ + stat_segment_main_t *sm = &stat_segment_main; + stat_segment_directory_entry_t *e; + + ASSERT (clib_mem_get_heap () == sm->heap); + + if (index > vec_len (sm->directory_vector)) + return; + + e = &sm->directory_vector[index]; + + clib_mem_set_heap (oldheap); + hash_unset (sm->directory_vector_by_name, &e->name); + clib_mem_set_heap (sm->heap); + + memset (e, 0, sizeof (*e)); + e->type = STAT_DIR_TYPE_EMPTY; +} + void vlib_stats_pop_heap (void *cm_arg, void *oldheap, u32 cindex, stat_directory_type_t type) @@ -109,20 +172,18 @@ vlib_stats_pop_heap (void *cm_arg, void *oldheap, u32 cindex, /* Lookup hash-table is on the main heap */ stat_segment_name = cm->stat_segment_name ? cm->stat_segment_name : cm->name; - u32 next_vector_index = vec_len (sm->directory_vector); clib_mem_set_heap (oldheap); /* Exit stats segment */ - u32 vector_index = lookup_or_create_hash_index ((u8 *) stat_segment_name, - next_vector_index); + u32 vector_index = lookup_hash_index ((u8 *) stat_segment_name); /* Back to stats segment */ clib_mem_set_heap (sm->heap); /* Re-enter stat segment */ /* Update the vector */ - if (vector_index == next_vector_index) + if (vector_index == STAT_SEGMENT_INDEX_INVALID) { /* New */ strncpy (e.name, stat_segment_name, 128 - 1); e.type = type; - vec_add1 (sm->directory_vector, e); + vector_index = vlib_stats_create_counter (&e, oldheap); } stat_segment_directory_entry_t *ep = &sm->directory_vector[vector_index]; @@ -168,23 +229,19 @@ vlib_stats_register_error_index (void *oldheap, u8 * name, u64 * em_vec, ASSERT (shared_header); vlib_stat_segment_lock (); - u32 next_vector_index = vec_len (sm->directory_vector); clib_mem_set_heap (oldheap); /* Exit stats segment */ - - u32 vector_index = lookup_or_create_hash_index (name, - next_vector_index); - + u32 vector_index = lookup_hash_index (name); /* Back to stats segment */ clib_mem_set_heap (sm->heap); /* Re-enter stat segment */ - if (next_vector_index == vector_index) + if (vector_index == STAT_SEGMENT_INDEX_INVALID) { memcpy (e.name, name, vec_len (name)); e.name[vec_len (name)] = '\0'; e.type = STAT_DIR_TYPE_ERROR_INDEX; e.offset = index; e.offset_vector = 0; - vec_add1 (sm->directory_vector, e); + vector_index = vlib_stats_create_counter (&e, oldheap); /* Warn clients to refresh any pointers they might be holding */ shared_header->directory_offset = @@ -377,6 +434,10 @@ format_stat_dir_entry (u8 * s, va_list * args) type_name = "NameVector"; break; + case STAT_DIR_TYPE_EMPTY: + type_name = "empty"; + break; + default: type_name = "illegal!"; break; @@ -410,6 +471,11 @@ show_stat_segment_command_fn (vlib_main_t * vm, for (i = 0; i < vec_len (show_data); i++) { + stat_segment_directory_entry_t *ep = vec_elt_at_index (show_data, i); + + if (ep->type == STAT_DIR_TYPE_EMPTY) + continue; + vlib_cli_output (vm, "%-100U", format_stat_dir_entry, vec_elt_at_index (show_data, i)); } @@ -761,21 +827,18 @@ stat_segment_register_gauge (u8 * name, stat_segment_update_fn update_fn, ASSERT (shared_header); - u32 next_vector_index = vec_len (sm->directory_vector); - u32 vector_index = lookup_or_create_hash_index (name, - next_vector_index); - - if (vector_index < next_vector_index) /* Already registered */ - return clib_error_return (0, "%v is alreadty registered", name); + u32 vector_index = lookup_hash_index (name); - oldheap = vlib_stats_push_heap (NULL); - vlib_stat_segment_lock (); + if (vector_index != STAT_SEGMENT_INDEX_INVALID) /* Already registered */ + return clib_error_return (0, "%v is already registered", name); memset (&e, 0, sizeof (e)); e.type = STAT_DIR_TYPE_SCALAR_INDEX; - memcpy (e.name, name, vec_len (name)); - vec_add1 (sm->directory_vector, e); + + oldheap = vlib_stats_push_heap (NULL); + vlib_stat_segment_lock (); + vector_index = vlib_stats_create_counter (&e, oldheap); shared_header->directory_offset = stat_segment_offset (shared_header, sm->directory_vector); @@ -787,7 +850,7 @@ stat_segment_register_gauge (u8 * name, stat_segment_update_fn update_fn, pool_get (sm->gauges, gauge); gauge->fn = update_fn; gauge->caller_index = caller_index; - gauge->directory_index = next_vector_index; + gauge->directory_index = vector_index; return NULL; } @@ -803,21 +866,19 @@ stat_segment_register_state_counter (u8 * name, u32 * index) ASSERT (shared_header); ASSERT (vlib_get_thread_index () == 0); - u32 next_vector_index = vec_len (sm->directory_vector); - u32 vector_index = lookup_or_create_hash_index (name, - next_vector_index); + u32 vector_index = lookup_hash_index (name); - if (vector_index < next_vector_index) /* Already registered */ + if (vector_index != STAT_SEGMENT_INDEX_INVALID) /* Already registered */ return clib_error_return (0, "%v is already registered", name); - oldheap = vlib_stats_push_heap (NULL); - vlib_stat_segment_lock (); - memset (&e, 0, sizeof (e)); e.type = STAT_DIR_TYPE_SCALAR_INDEX; - memcpy (e.name, name, vec_len (name)); - vec_add1 (sm->directory_vector, e); + + oldheap = vlib_stats_push_heap (NULL); + vlib_stat_segment_lock (); + + vector_index = vlib_stats_create_counter (&e, oldheap); shared_header->directory_offset = stat_segment_offset (shared_header, sm->directory_vector); @@ -825,7 +886,7 @@ stat_segment_register_state_counter (u8 * name, u32 * index) vlib_stat_segment_unlock (); clib_mem_set_heap (oldheap); - *index = next_vector_index; + *index = vector_index; return 0; } @@ -835,6 +896,7 @@ stat_segment_deregister_state_counter (u32 index) stat_segment_main_t *sm = &stat_segment_main; stat_segment_shared_header_t *shared_header = sm->shared_header; stat_segment_directory_entry_t *e; + void *oldheap; ASSERT (shared_header); @@ -845,8 +907,14 @@ stat_segment_deregister_state_counter (u32 index) if (e->type != STAT_DIR_TYPE_SCALAR_INDEX) return clib_error_return (0, "%u index cannot be deleted", index); - hash_unset (sm->directory_vector_by_name, &e->name); - vec_del1 (sm->directory_vector, index); + oldheap = vlib_stats_push_heap (NULL); + vlib_stat_segment_lock (); + + vlib_stats_delete_counter (index, oldheap); + + vlib_stat_segment_unlock (); + clib_mem_set_heap (oldheap); + return 0; }