23 #ifndef __included_bihash_template_h__ 24 #define __included_bihash_template_h__ 33 #error BIHASH_TYPE not defined 36 #ifdef BIHASH_32_64_SVM 37 #undef HAVE_MEMFD_CREATE 40 #define F_LINUX_SPECIFIC_BASE 1024 41 #define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9) 42 #define F_SEAL_SHRINK (2) 44 #define BIHASH_FREELIST_LENGTH 17 48 #define __bv(a,b) _bv(a,b) 49 #define BV(a) __bv(a,BIHASH_TYPE) 51 #define _bvt(a,b) a##b##_t 52 #define __bvt(a,b) _bvt(a,b) 53 #define BVT(a) __bvt(a,BIHASH_TYPE) 55 #define _bvs(a,b) struct a##b 56 #define __bvs(a,b) _bvs(a,b) 57 #define BVS(a) __bvs(a,BIHASH_TYPE) 60 #define OVERFLOW_ASSERT(x) ASSERT(((x) & 0xFFFFFFFF00000000ULL) == 0) 61 #define u64_to_pointer(x) (void *)(u32)((x)) 62 #define pointer_to_u64(x) (u64)(u32)((x)) 64 #define OVERFLOW_ASSERT(x) 65 #define u64_to_pointer(x) (void *)((x)) 66 #define pointer_to_u64(x) (u64)((x)) 69 typedef struct BV (clib_bihash_value)
78 #define BIHASH_BUCKET_OFFSET_BITS 36 94 }
BVT (clib_bihash_bucket);
104 u64 alloc_arena_next;
105 u64 alloc_arena_size;
107 u64 alloc_lock_as_u64;
110 u64 freelists_as_u64;
115 })
BVT (clib_bihash_shared_header);
123 BVT (clib_bihash_bucket) * buckets;
124 volatile u32 *alloc_lock;
127 int *working_copy_lengths;
128 BVT (clib_bihash_bucket) saved_bucket;
138 BVT (clib_bihash_shared_header) * sh;
141 BVT (clib_bihash_shared_header) sh;
145 volatile u8 instantiated;
153 #if BIHASH_ENABLE_STATS 154 void (*inc_stats_callback) (BVS (clib_bihash) *,
int stat_id,
u64 count);
157 void *inc_stats_context;
164 BVT (clib_bihash) *
h;
169 u8 instantiate_immediately;
170 u8 dont_add_to_all_bihash_list;
171 }
BVT (clib_bihash_init2_args);
176 #undef alloc_arena_next 177 #undef alloc_arena_size 179 #undef CLIB_BIHASH_READY_MAGIC 180 #define alloc_arena_next(h) (((h)->sh)->alloc_arena_next) 181 #define alloc_arena_size(h) (((h)->sh)->alloc_arena_size) 182 #define alloc_arena(h) ((h)->alloc_arena) 183 #define CLIB_BIHASH_READY_MAGIC 0xFEEDFACE 185 #undef alloc_arena_next 186 #undef alloc_arena_size 188 #undef CLIB_BIHASH_READY_MAGIC 189 #define alloc_arena_next(h) ((h)->sh.alloc_arena_next) 190 #define alloc_arena_size(h) ((h)->sh.alloc_arena_size) 191 #define alloc_arena(h) ((h)->alloc_arena) 192 #define CLIB_BIHASH_READY_MAGIC 0 195 #ifndef BIHASH_STAT_IDS 196 #define BIHASH_STAT_IDS 1 198 #define foreach_bihash_stat \ 208 _(working_copy_lost) \ 213 #define _(a) BIHASH_STAT_##a, 217 }
BVT (clib_bihash_stat_id);
220 static inline void BV (clib_bihash_increment_stat) (
BVT (clib_bihash) *
h,
223 #if BIHASH_ENABLE_STATS 225 h->inc_stats_callback (h, stat_id,
count);
229 #if BIHASH_ENABLE_STATS 230 static inline void BV (clib_bihash_set_stats_callback)
231 (
BVT (clib_bihash) *
h, void (*cb) (
BVT (clib_bihash) *, int,
u64),
234 h->inc_stats_callback = cb;
235 h->inc_stats_context =
ctx;
240 static inline void BV (clib_bihash_alloc_lock) (
BVT (clib_bihash) *
h)
242 while (__atomic_test_and_set (h->alloc_lock, __ATOMIC_ACQUIRE))
246 static inline void BV (clib_bihash_alloc_unlock) (
BVT (clib_bihash) *
h)
248 __atomic_clear (h->alloc_lock, __ATOMIC_RELEASE);
251 static inline void BV (clib_bihash_lock_bucket) (
BVT (clib_bihash_bucket) * b)
253 BVT (clib_bihash_bucket) unlocked_bucket, locked_bucket;
257 locked_bucket.as_u64 = unlocked_bucket.as_u64 = b->as_u64;
258 unlocked_bucket.lock = 0;
259 locked_bucket.lock = 1;
262 while (__atomic_compare_exchange_n (&b->as_u64, &unlocked_bucket.as_u64,
263 locked_bucket.as_u64, 1 ,
265 __ATOMIC_ACQUIRE) == 0);
268 static inline void BV (clib_bihash_unlock_bucket)
269 (
BVT (clib_bihash_bucket) * b)
284 static inline int BV (clib_bihash_bucket_is_empty)
285 (
BVT (clib_bihash_bucket) * b)
288 return b->offset == 0;
296 hp = (
u8 *) (
uword) alloc_arena (h);
305 void BV (clib_bihash_init2) (
BVT (clib_bihash_init2_args) *
a);
308 void BV (clib_bihash_master_init_svm)
310 void BV (clib_bihash_slave_init_svm)
311 (
BVT (clib_bihash) *
h,
char *
name,
int fd);
314 void BV (clib_bihash_set_kvp_format_fn) (
BVT (clib_bihash) *
h,
320 BVT (clib_bihash_kv) * add_v,
int is_add);
321 int BV (clib_bihash_add_or_overwrite_stale) (
BVT (clib_bihash) *
h,
322 BVT (clib_bihash_kv) * add_v,
323 int (*is_stale_cb) (
BVT 327 int BV (clib_bihash_search) (
BVT (clib_bihash) *
h,
328 BVT (clib_bihash_kv) * search_v,
329 BVT (clib_bihash_kv) * return_v);
331 #define BIHASH_WALK_STOP 0 332 #define BIHASH_WALK_CONTINUE 1 349 (
BVT (clib_bihash) *
h,
u64 hash,
BVT (clib_bihash_kv) * key_result)
353 BVT (clib_bihash_bucket) * b;
359 bucket_index = hash & (h->nbuckets - 1);
360 b = &h->buckets[bucket_index];
367 volatile BVT (clib_bihash_bucket) * bv = b;
372 hash >>= h->log2_nbuckets;
378 v += (b->linear_search == 0) ? hash & ((1 << b->log2_pages) - 1) : 0;
380 limit <<= b->log2_pages;
382 for (i = 0; i < limit; i++)
384 if (BV (clib_bihash_key_compare) (v->kvp[
i].key, key_result->key))
386 *key_result = v->kvp[
i];
394 (
BVT (clib_bihash) *
h,
BVT (clib_bihash_kv) * key_result)
398 hash = BV (clib_bihash_hash) (key_result);
404 (
BVT (clib_bihash) *
h,
u64 hash)
407 BVT (clib_bihash_bucket) * b;
409 bucket_index = hash & (h->nbuckets - 1);
410 b = &h->buckets[bucket_index];
416 (
BVT (clib_bihash) *
h,
u64 hash)
420 BVT (clib_bihash_bucket) * b;
425 bucket_index = hash & (h->nbuckets - 1);
426 b = &h->buckets[bucket_index];
431 hash >>= h->log2_nbuckets;
434 v += (b->linear_search == 0) ? hash & ((1 << b->log2_pages) - 1) : 0;
439 static inline int BV (clib_bihash_search_inline_2_with_hash)
440 (
BVT (clib_bihash) *
h,
441 u64 hash,
BVT (clib_bihash_kv) * search_key,
BVT (clib_bihash_kv) * valuep)
445 BVT (clib_bihash_bucket) * b;
453 bucket_index = hash & (h->nbuckets - 1);
454 b = &h->buckets[bucket_index];
461 volatile BVT (clib_bihash_bucket) * bv = b;
466 hash >>= h->log2_nbuckets;
471 v += (b->linear_search == 0) ? hash & ((1 << b->log2_pages) - 1) : 0;
473 limit <<= b->log2_pages;
475 for (i = 0; i < limit; i++)
477 if (BV (clib_bihash_key_compare) (v->kvp[
i].key, search_key->key))
487 (
BVT (clib_bihash) *
h,
488 BVT (clib_bihash_kv) * search_key,
BVT (clib_bihash_kv) * valuep)
492 hash = BV (clib_bihash_hash) (search_key);
494 return BV (clib_bihash_search_inline_2_with_hash) (
h, hash, search_key,
int clib_bihash_search_inline_with_hash(clib_bihash *h, u64 hash, clib_bihash_kv *in_out_kv)
Search a bi-hash table, use supplied hash code.
u8 pad[3]
log2 (size of the packing page block)
#define BIHASH_KVP_PER_PAGE
void clib_bihash_free(clib_bihash *h)
Destroy a bounded index extensible hash table.
Fixed length block allocator.
for(i=1;i<=collision_buckets;i++)
int clib_bihash_add_del(clib_bihash *h, clib_bihash_kv *add_v, int is_add)
Add or delete a (key,value) pair from a bi-hash table.
static uword clib_bihash_get_offset(clib_bihash *h, void *v)
Get clib mheap offset given a pointer.
int(* clib_bihash_foreach_key_value_pair_cb)(clib_bihash_kv *kv, void *ctx)
void clib_bihash_foreach_key_value_pair(clib_bihash *h, clib_bihash_foreach_key_value_pair_cb *callback, void *arg)
Visit active (key,value) pairs in a bi-hash table.
int clib_bihash_search_inline(clib_bihash *h, clib_bihash_kv *in_out_kv)
Search a bi-hash table.
void clib_bihash_init(clib_bihash *h, char *name, u32 nbuckets, uword memory_size)
initialize a bounded index extensible hash table
void clib_bihash_prefetch_bucket(clib_bihash *h, u64 hash)
Prefetch a bi-hash bucket given a hash code.
#define CLIB_PREFETCH(addr, size, type)
void clib_bihash_prefetch_data(clib_bihash *h, u64 hash)
Prefetch bi-hash (key,value) data given a hash code.
int clib_bihash_search_inline_2(clib_bihash *h, clib_bihash_kv *search_key, clib_bihash_kv *valuep)
Search a bi-hash table.
void clib_bihash_copied(void *dst, void *src)
template key/value backing page structure
struct clib_bihash_value offset
template key/value backing page structure
#define CLIB_MEMORY_BARRIER()
static void * clib_bihash_get_value(clib_bihash *h, uword offset)
Get pointer to value page given its clib mheap offset.
void ** clib_all_bihashes
#define CLIB_CACHE_LINE_BYTES
void * clib_all_bihash_set_heap(void)
#define STATIC_ASSERT_SIZEOF(d, s)