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 #ifndef BIHASH_LOG2_HUGEPAGE_SIZE 49 #define BIHASH_LOG2_HUGEPAGE_SIZE 21 53 #define __bv(a,b) _bv(a,b) 54 #define BV(a) __bv(a,BIHASH_TYPE) 56 #define _bvt(a,b) a##b##_t 57 #define __bvt(a,b) _bvt(a,b) 58 #define BVT(a) __bvt(a,BIHASH_TYPE) 60 #define _bvs(a,b) struct a##b 61 #define __bvs(a,b) _bvs(a,b) 62 #define BVS(a) __bvs(a,BIHASH_TYPE) 65 #define OVERFLOW_ASSERT(x) ASSERT(((x) & 0xFFFFFFFF00000000ULL) == 0) 66 #define u64_to_pointer(x) (void *)(u32)((x)) 67 #define pointer_to_u64(x) (u64)(u32)((x)) 69 #define OVERFLOW_ASSERT(x) 70 #define u64_to_pointer(x) (void *)((x)) 71 #define pointer_to_u64(x) (u64)((x)) 74 typedef struct BV (clib_bihash_value)
83 #define BIHASH_BUCKET_OFFSET_BITS 36 99 }
BVT (clib_bihash_bucket);
109 u64 alloc_arena_next;
110 u64 alloc_arena_size;
111 u64 alloc_arena_mapped;
113 u64 alloc_lock_as_u64;
116 u64 freelists_as_u64;
121 })
BVT (clib_bihash_shared_header);
127 BVS (clib_bihash_alloc_chunk)
141 BVS (clib_bihash_alloc_chunk) * prev, *next;
143 }
BVT (clib_bihash_alloc_chunk);
148 BVT (clib_bihash_bucket) * buckets;
149 volatile u32 *alloc_lock;
152 int *working_copy_lengths;
153 BVT (clib_bihash_bucket) saved_bucket;
161 BVT (clib_bihash_alloc_chunk) * chunks;
166 BVT (clib_bihash_shared_header) * sh;
169 BVT (clib_bihash_shared_header) sh;
173 volatile u8 instantiated;
181 #if BIHASH_ENABLE_STATS 182 void (*inc_stats_callback) (BVS (clib_bihash) *,
int stat_id,
u64 count);
185 void *inc_stats_context;
192 BVT (clib_bihash) *
h;
197 u8 instantiate_immediately;
198 u8 dont_add_to_all_bihash_list;
199 }
BVT (clib_bihash_init2_args);
204 #undef alloc_arena_next 205 #undef alloc_arena_size 206 #undef alloc_arena_mapped 208 #undef CLIB_BIHASH_READY_MAGIC 209 #define alloc_arena_next(h) (((h)->sh)->alloc_arena_next) 210 #define alloc_arena_size(h) (((h)->sh)->alloc_arena_size) 211 #define alloc_arena_mapped(h) (((h)->sh)->alloc_arena_mapped) 212 #define alloc_arena(h) ((h)->alloc_arena) 213 #define CLIB_BIHASH_READY_MAGIC 0xFEEDFACE 215 #undef alloc_arena_next 216 #undef alloc_arena_size 217 #undef alloc_arena_mapped 219 #undef CLIB_BIHASH_READY_MAGIC 220 #define alloc_arena_next(h) ((h)->sh.alloc_arena_next) 221 #define alloc_arena_size(h) ((h)->sh.alloc_arena_size) 222 #define alloc_arena_mapped(h) ((h)->sh.alloc_arena_mapped) 223 #define alloc_arena(h) ((h)->alloc_arena) 224 #define CLIB_BIHASH_READY_MAGIC 0 227 #ifndef BIHASH_STAT_IDS 228 #define BIHASH_STAT_IDS 1 230 #define foreach_bihash_stat \ 240 _(working_copy_lost) \ 245 #define _(a) BIHASH_STAT_##a, 249 }
BVT (clib_bihash_stat_id);
252 static inline void BV (clib_bihash_increment_stat) (
BVT (clib_bihash) *
h,
255 #if BIHASH_ENABLE_STATS 257 h->inc_stats_callback (h, stat_id,
count);
261 #if BIHASH_ENABLE_STATS 262 static inline void BV (clib_bihash_set_stats_callback)
263 (
BVT (clib_bihash) *
h, void (*cb) (
BVT (clib_bihash) *, int,
u64),
266 h->inc_stats_callback = cb;
267 h->inc_stats_context =
ctx;
272 static inline void BV (clib_bihash_alloc_lock) (
BVT (clib_bihash) *
h)
274 while (__atomic_test_and_set (h->alloc_lock, __ATOMIC_ACQUIRE))
278 static inline void BV (clib_bihash_alloc_unlock) (
BVT (clib_bihash) *
h)
280 __atomic_clear (h->alloc_lock, __ATOMIC_RELEASE);
283 static inline void BV (clib_bihash_lock_bucket) (
BVT (clib_bihash_bucket) *
b)
286 BVT (clib_bihash_bucket)
mask = { .lock = 1 };
301 static inline void BV (clib_bihash_unlock_bucket)
302 (
BVT (clib_bihash_bucket) *
b)
316 static inline int BV (clib_bihash_bucket_is_empty)
317 (
BVT (clib_bihash_bucket) *
b)
321 return b->offset == 0;
323 return (
b->log2_pages == 0 &&
b->refcnt == 1);
331 hp = (
u8 *) (
uword) alloc_arena (h);
340 void BV (clib_bihash_init2) (
BVT (clib_bihash_init2_args) *
a);
343 void BV (clib_bihash_initiator_init_svm)
345 void BV (clib_bihash_responder_init_svm)
346 (
BVT (clib_bihash) *
h,
char *
name,
int fd);
349 void BV (clib_bihash_set_kvp_format_fn) (
BVT (clib_bihash) *
h,
355 BVT (clib_bihash_kv) * add_v,
int is_add);
356 int BV (clib_bihash_add_or_overwrite_stale) (
BVT (clib_bihash) *
h,
357 BVT (clib_bihash_kv) * add_v,
358 int (*is_stale_cb) (
BVT 362 int BV (clib_bihash_search) (
BVT (clib_bihash) *
h,
363 BVT (clib_bihash_kv) * search_v,
364 BVT (clib_bihash_kv) * return_v);
366 int BV (clib_bihash_is_initialised) (
const BVT (clib_bihash) *
h);
368 #define BIHASH_WALK_STOP 0 369 #define BIHASH_WALK_CONTINUE 1 386 BVT (clib_bihash_bucket) *
387 BV (clib_bihash_get_bucket) (
BVT (clib_bihash) *
h,
u64 hash)
389 #if BIHASH_KVP_AT_BUCKET_LEVEL 391 offset = (hash & (h->nbuckets - 1));
392 offset = offset * (
sizeof (
BVT (clib_bihash_bucket))
394 return ((
BVT (clib_bihash_bucket) *) (((
u8 *) h->buckets) + offset));
396 return h->buckets + (hash & (h->nbuckets - 1));
401 (
BVT (clib_bihash) *
h,
u64 hash,
BVT (clib_bihash_kv) * key_result)
404 BVT (clib_bihash_bucket) *
b;
408 static const BVT (clib_bihash_bucket)
mask = {
414 #if BIHASH_LAZY_INSTANTIATE 419 b = BV (clib_bihash_get_bucket) (
h, hash);
426 volatile BVT (clib_bihash_bucket) * bv =
b;
439 limit <<=
b->log2_pages;
444 for (i = 0; i < limit; i++)
446 if (BV (clib_bihash_key_compare) (v->kvp[
i].key, key_result->key))
448 *key_result = v->kvp[
i];
456 (
BVT (clib_bihash) *
h,
BVT (clib_bihash_kv) * key_result)
460 hash = BV (clib_bihash_hash) (key_result);
466 (
BVT (clib_bihash) *
h,
u64 hash)
474 (
BVT (clib_bihash) *
h,
u64 hash)
477 BVT (clib_bihash_bucket) *
b;
479 #if BIHASH_LAZY_INSTANTIATE 484 b = BV (clib_bihash_get_bucket) (
h, hash);
498 static inline int BV (clib_bihash_search_inline_2_with_hash)
499 (
BVT (clib_bihash) *
h,
500 u64 hash,
BVT (clib_bihash_kv) * search_key,
BVT (clib_bihash_kv) * valuep)
503 BVT (clib_bihash_bucket) *
b;
507 static const BVT (clib_bihash_bucket)
mask = {
515 #if BIHASH_LAZY_INSTANTIATE 520 b = BV (clib_bihash_get_bucket) (
h, hash);
527 volatile BVT (clib_bihash_bucket) * bv =
b;
540 limit <<=
b->log2_pages;
545 for (i = 0; i < limit; i++)
547 if (BV (clib_bihash_key_compare) (v->kvp[
i].key, search_key->key))
557 (
BVT (clib_bihash) *
h,
558 BVT (clib_bihash_kv) * search_key,
BVT (clib_bihash_kv) * valuep)
562 hash = BV (clib_bihash_hash) (search_key);
564 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 CLIB_CACHE_LINE_ALIGN_MARK(mark)
#define BIHASH_KVP_PER_PAGE
void clib_bihash_free(clib_bihash *h)
Destroy a bounded index extensible hash table.
Fixed length block allocator.
__clib_export void ** clib_all_bihashes
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.
#define clib_atomic_fetch_or(a, b)
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 BIHASH_KVP_AT_BUCKET_LEVEL
#define CLIB_PREFETCH(addr, size, type)
sll srl srl sll sra u16x4 i
void clib_bihash_prefetch_data(clib_bihash *h, u64 hash)
Prefetch bi-hash (key,value) data given a hash code.
__clib_export void clib_bihash_copied(void *dst, void *src)
int clib_bihash_search_inline_2(clib_bihash *h, clib_bihash_kv *search_key, clib_bihash_kv *valuep)
Search a bi-hash table.
#define BIHASH_BUCKET_PREFETCH_CACHE_LINES
static uword extract_bits(uword x, int start, int count)
template key/value backing page structure
struct clib_bihash_value offset
template key/value backing page structure
__clib_export clib_mem_heap_t * clib_all_bihash_set_heap(void)
static void * clib_bihash_get_value(clib_bihash *h, uword offset)
Get pointer to value page given its clib mheap offset.
#define CLIB_CACHE_LINE_BYTES
#define STATIC_ASSERT_SIZEOF(d, s)