stat_validate_counter_vector2 (ep, tm->n_vlib_mains, max);
}
-always_inline void
-stat_set_simple_counter (stat_segment_directory_entry_t * ep,
- u32 thread_index, u32 index, u64 value)
-{
- ASSERT (ep->data);
- counter_t **counters = ep->data;
- counter_t *cb = counters[thread_index];
- cb[index] = value;
-}
-
void
vlib_stats_pop_heap2 (u64 * error_vector, u32 thread_index, void *oldheap,
int lock)
* Create a new entry and add name to directory hash.
* Returns ~0 if name exists.
* Called from main heap.
+ * The name is either C-string or nul-terminated vector
*/
u32
stat_segment_new_entry (u8 *name, stat_directory_type_t t)
memset (&e, 0, sizeof (e));
e.type = t;
- memcpy (e.name, name, vec_len (name));
+ strcpy_s (e.name, sizeof (e.name), (char *) name);
oldheap = vlib_stats_push_heap (NULL);
vlib_stat_segment_lock ();
static void
do_stat_segment_updates (vlib_main_t *vm, stat_segment_main_t *sm)
{
- f64 vector_rate;
u64 input_packets;
f64 dt, now;
- vlib_main_t *this_vlib_main;
- int i;
static int num_worker_threads_set;
/*
*/
if (PREDICT_FALSE (num_worker_threads_set == 0))
{
- void *oldheap = clib_mem_set_heap (sm->heap);
- vlib_stat_segment_lock ();
-
- stat_validate_counter_vector (&sm->directory_vector
- [STAT_COUNTER_VECTOR_RATE_PER_WORKER], 0);
+ vlib_thread_main_t *tm = vlib_get_thread_main ();
+ ASSERT (tm->n_vlib_mains > 0);
+ stat_provider_register_vector_rate (tm->n_vlib_mains - 1);
+ sm->directory_vector[STAT_COUNTER_NUM_WORKER_THREADS].value =
+ tm->n_vlib_mains - 1;
num_worker_threads_set = 1;
- vlib_stat_segment_unlock ();
- clib_mem_set_heap (oldheap);
}
- /*
- * Compute per-worker vector rates, and the average vector rate
- * across all workers
- */
- vector_rate = 0.0;
-
- for (i = 0; i < vlib_get_n_threads (); i++)
- {
-
- f64 this_vector_rate;
-
- this_vlib_main = vlib_get_main_by_index (i);
-
- this_vector_rate = vlib_internal_node_vector_rate (this_vlib_main);
- vlib_clear_internal_node_vector_rate (this_vlib_main);
-
- vector_rate += this_vector_rate;
-
- /* Set the per-worker rate */
- stat_set_simple_counter (&sm->directory_vector
- [STAT_COUNTER_VECTOR_RATE_PER_WORKER], i, 0,
- this_vector_rate);
- }
-
- /* And set the system average rate */
- vector_rate /= (f64) (i > 1 ? i - 1 : 1);
-
- sm->directory_vector[STAT_COUNTER_VECTOR_RATE].value = vector_rate;
-
/*
* Compute the aggregate input rate
*/
/* *INDENT-OFF* */
stat_segment_gauges_pool_t *g;
pool_foreach (g, sm->gauges)
- {
- g->fn(&sm->directory_vector[g->directory_index], g->caller_index);
- }
+ {
+ if (g->enabled)
+ g->fn (&sm->directory_vector[g->directory_index], g->caller_index);
+ }
/* *INDENT-ON* */
/* Heartbeat, so clients detect we're still here */
* Add a data provider (via callback) for a given stats entry.
* TODO: Add support for per-provider interval.
*/
-void
+uword
stat_segment_poll_add (u32 vector_index, stat_segment_update_fn update_fn,
- u32 caller_index, u32 interval)
+ u32 caller_index, u32 interval, u8 enabled)
{
stat_segment_main_t *sm = &stat_segment_main;
stat_segment_gauges_pool_t *gauge;
gauge->fn = update_fn;
gauge->caller_index = caller_index;
gauge->directory_index = vector_index;
+ gauge->enabled = enabled;
- return;
+ return pool_elts (sm->gauges) - 1;
+}
+
+/*
+ * Enable (or disable) a callback for a stats entry
+ */
+void
+stat_segment_poll_state (uword index, u8 enabled)
+{
+ stat_segment_main_t *sm = &stat_segment_main;
+ stat_segment_gauges_pool_t *gauge = pool_elt_at_index (sm->gauges, index);
+
+ ASSERT (gauge);
+
+ gauge->enabled = enabled;
}
/*
* Deprecated, replace with stat_segment_new_entry + stat_segment_pool_add
*/
clib_error_t *
-stat_segment_register_gauge (u8 * name, stat_segment_update_fn update_fn,
+stat_segment_register_gauge (u8 *name, stat_segment_update_fn update_fn,
u32 caller_index)
{
- stat_segment_main_t *sm = &stat_segment_main;
- stat_segment_gauges_pool_t *gauge;
-
u32 vector_index = stat_segment_new_entry (name, STAT_DIR_TYPE_SCALAR_INDEX);
if (vector_index == ~0) /* Already registered */
return clib_error_return (0, "%v is already registered", name);
- pool_get (sm->gauges, gauge);
- gauge->fn = update_fn;
- gauge->caller_index = caller_index;
- gauge->directory_index = vector_index;
+ stat_segment_poll_add (vector_index, update_fn, caller_index, -1, true);
return NULL;
}