diff options
author | Dave Barach <dave@barachs.net> | 2019-05-03 12:58:01 -0400 |
---|---|---|
committer | Florin Coras <florin.coras@gmail.com> | 2019-05-07 15:52:38 +0000 |
commit | 2ce28d6014f44a98f5b3387a4709dd56dbc2f8df (patch) | |
tree | 97b1a43966f0f22eab4e7e8904b047a984a3c1c0 /src/plugins/unittest | |
parent | c74009dce1b2f1466112775a68a5608d754c7c76 (diff) |
Add bihash statistics hook
Example / unit-test in .../src/plugins/unittest/bihash_test.c
Change-Id: I23fd0ba742d65291667a755965aee1a3d3477ca2
Signed-off-by: Dave Barach <dave@barachs.net>
Diffstat (limited to 'src/plugins/unittest')
-rw-r--r-- | src/plugins/unittest/bihash_test.c | 68 |
1 files changed, 67 insertions, 1 deletions
diff --git a/src/plugins/unittest/bihash_test.c b/src/plugins/unittest/bihash_test.c index 5768d0e14ea..2dbc6b1b002 100644 --- a/src/plugins/unittest/bihash_test.c +++ b/src/plugins/unittest/bihash_test.c @@ -20,13 +20,28 @@ #include <stdio.h> #include <pthread.h> -#include <vppinfra/bihash_8_8.h> +#include <vppinfra/bihash_8_8_stats.h> #include <vppinfra/bihash_template.h> #include <vppinfra/bihash_template.c> typedef struct { + u64 alloc_add; + u64 add; + u64 split_add; + u64 replace; + u64 update; + u64 del; + u64 del_free; + u64 linear; + u64 resplit; + u64 working_copy_lost; + u64 *splits; +} bihash_stats_t; + +typedef struct +{ volatile u32 thread_barrier; volatile u32 threads_running; volatile u64 sequence_number; @@ -51,10 +66,53 @@ typedef struct /* convenience */ vlib_main_t *vlib_main; + + CLIB_CACHE_LINE_ALIGN_MARK (stat_align); + bihash_stats_t stats; + } bihash_test_main_t; static bihash_test_main_t bihash_test_main; +u8 * +format_bihash_stats (u8 * s, va_list * args) +{ + BVT (clib_bihash) * h = va_arg (*args, BVT (clib_bihash) *); + int verbose = va_arg (*args, int); + int i; + bihash_stats_t *sp = h->inc_stats_context; + +#define _(a) s = format (s, "%20s: %lld\n", #a, sp->a); + foreach_bihash_stat; +#undef _ + for (i = 0; i < vec_len (sp->splits); i++) + { + if (sp->splits[i] > 0 || verbose) + s = format (s, " splits[%d]: %lld\n", 1 << i, sp->splits[i]); + } + return s; +} + + +static void +inc_stats_callback (BVT (clib_bihash) * h, int stat_id, u64 count) +{ + uword *statp = h->inc_stats_context; + bihash_stats_t *for_splits; + + if (PREDICT_TRUE (stat_id * sizeof (u64) + < STRUCT_OFFSET_OF (bihash_stats_t, splits))) + { + statp[stat_id] += count; + return; + } + + for_splits = h->inc_stats_context; + vec_validate (for_splits->splits, count); + for_splits->splits[count] += 1; +} + + static clib_error_t * test_bihash_vec64 (bihash_test_main_t * tm) { @@ -69,6 +127,7 @@ test_bihash_vec64 (bihash_test_main_t * tm) h = &tm->hash; BV (clib_bihash_init) (h, "test", user_buckets, user_memory_size); + BV (clib_bihash_set_stats_callback) (h, inc_stats_callback, &tm->stats); before = clib_time_now (&tm->clib_time); @@ -143,6 +202,7 @@ test_bihash_threads (bihash_test_main_t * tm) h = &tm->hash; BV (clib_bihash_init) (h, "test", tm->nbuckets, tm->hash_memory_size); + BV (clib_bihash_set_stats_callback) (h, inc_stats_callback, &tm->stats); tm->thread_barrier = 1; @@ -176,6 +236,7 @@ test_bihash_threads (bihash_test_main_t * tm) 0.0 ? ((f64) ((u64) tm->nthreads * (u64) tm->nitems)) / delta : 0.0); + fformat (stdout, "Stats:\n%U", format_bihash_stats, h, 1 /* verbose */ ); BV (clib_bihash_free) (h); return 0; } @@ -204,6 +265,7 @@ test_bihash (bihash_test_main_t * tm) h = &tm->hash; BV (clib_bihash_init) (h, "test", tm->nbuckets, tm->hash_memory_size); + BV (clib_bihash_set_stats_callback) (h, inc_stats_callback, &tm->stats); for (acycle = 0; acycle < tm->ncycles; acycle++) { @@ -384,6 +446,8 @@ test_bihash (bihash_test_main_t * tm) /* ASSERTs if any items remain */ BV (clib_bihash_foreach_key_value_pair) (h, count_items, 0); + fformat (stdout, "Stats:\n%U", format_bihash_stats, h, 1 /* verbose */ ); + BV (clib_bihash_free) (h); vec_free (tm->keys); @@ -407,6 +471,8 @@ test_bihash_command_fn (vlib_main_t * vm, tm->report_every_n = 50000; tm->seed = 0x1badf00d; + memset (&tm->stats, 0, sizeof (tm->stats)); + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "seed %u", &tm->seed)) |