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) 56 #define OVERFLOW_ASSERT(x) ASSERT(((x) & 0xFFFFFFFF00000000ULL) == 0) 57 #define u64_to_pointer(x) (void *)(u32)((x)) 58 #define pointer_to_u64(x) (u64)(u32)((x)) 60 #define OVERFLOW_ASSERT(x) 61 #define u64_to_pointer(x) (void *)((x)) 62 #define pointer_to_u64(x) (u64)((x)) 65 typedef struct BV (clib_bihash_value)
69 BVT (clib_bihash_kv) kvp[BIHASH_KVP_PER_PAGE];
72 }
BVT (clib_bihash_value);
74 #define BIHASH_BUCKET_OFFSET_BITS 36 82 u64 offset:BIHASH_BUCKET_OFFSET_BITS;
90 }
BVT (clib_bihash_bucket);
100 u64 alloc_arena_next;
101 u64 alloc_arena_size;
103 u64 alloc_lock_as_u64;
106 u64 freelists_as_u64;
111 })
BVT (clib_bihash_shared_header);
118 BVT (clib_bihash_bucket) * buckets;
119 volatile u32 *alloc_lock;
121 BVT (clib_bihash_value) ** working_copies;
122 int *working_copy_lengths;
123 BVT (clib_bihash_bucket) saved_bucket;
132 BVT (clib_bihash_shared_header) * sh;
135 BVT (clib_bihash_shared_header) sh;
148 #undef alloc_arena_next 149 #undef alloc_arena_size 151 #undef CLIB_BIHASH_READY_MAGIC 152 #define alloc_arena_next(h) (((h)->sh)->alloc_arena_next) 153 #define alloc_arena_size(h) (((h)->sh)->alloc_arena_size) 154 #define alloc_arena(h) ((h)->alloc_arena) 155 #define CLIB_BIHASH_READY_MAGIC 0xFEEDFACE 157 #undef alloc_arena_next 158 #undef alloc_arena_size 160 #undef CLIB_BIHASH_READY_MAGIC 161 #define alloc_arena_next(h) ((h)->sh.alloc_arena_next) 162 #define alloc_arena_size(h) ((h)->sh.alloc_arena_size) 163 #define alloc_arena(h) ((h)->alloc_arena) 164 #define CLIB_BIHASH_READY_MAGIC 0 167 static inline void BV (clib_bihash_alloc_lock) (
BVT (clib_bihash) *
h)
169 while (__atomic_test_and_set (h->alloc_lock, __ATOMIC_ACQUIRE))
173 static inline void BV (clib_bihash_alloc_unlock) (
BVT (clib_bihash) *
h)
175 __atomic_clear (h->alloc_lock, __ATOMIC_RELEASE);
178 static inline void BV (clib_bihash_lock_bucket) (
BVT (clib_bihash_bucket) * b)
180 BVT (clib_bihash_bucket) unlocked_bucket, locked_bucket;
184 locked_bucket.as_u64 = unlocked_bucket.as_u64 = b->as_u64;
185 unlocked_bucket.lock = 0;
186 locked_bucket.lock = 1;
189 while (__atomic_compare_exchange_n (&b->as_u64, &unlocked_bucket.as_u64,
190 locked_bucket.as_u64, 1 ,
192 __ATOMIC_ACQUIRE) == 0);
195 static inline void BV (clib_bihash_unlock_bucket)
196 (
BVT (clib_bihash_bucket) * b)
211 static inline int BV (clib_bihash_bucket_is_empty)
212 (
BVT (clib_bihash_bucket) * b)
215 return b->offset == 0;
223 hp = (
u8 *) (
uword) alloc_arena (h);
233 void BV (clib_bihash_master_init_svm)
235 void BV (clib_bihash_slave_init_svm)
236 (
BVT (clib_bihash) *
h,
char *
name,
int fd);
239 void BV (clib_bihash_set_kvp_format_fn) (
BVT (clib_bihash) *
h,
245 BVT (clib_bihash_kv) * add_v,
int is_add);
246 int BV (clib_bihash_add_or_overwrite_stale) (
BVT (clib_bihash) *
h,
247 BVT (clib_bihash_kv) * add_v,
248 int (*is_stale_cb) (
BVT 252 int BV (clib_bihash_search) (
BVT (clib_bihash) *
h,
253 BVT (clib_bihash_kv) * search_v,
254 BVT (clib_bihash_kv) * return_v);
257 void *callback,
void *arg);
264 (
BVT (clib_bihash) *
h,
u64 hash,
BVT (clib_bihash_kv) * key_result)
267 BVT (clib_bihash_value) *
v;
268 BVT (clib_bihash_bucket) * b;
271 bucket_index = hash & (h->nbuckets - 1);
272 b = &h->buckets[bucket_index];
279 volatile BVT (clib_bihash_bucket) * bv = b;
284 hash >>= h->log2_nbuckets;
290 v += (b->linear_search == 0) ? hash & ((1 << b->log2_pages) - 1) : 0;
292 limit <<= b->log2_pages;
294 for (i = 0; i < limit; i++)
296 if (BV (clib_bihash_key_compare) (
v->kvp[
i].key, key_result->key))
298 *key_result =
v->kvp[
i];
306 (
BVT (clib_bihash) *
h,
BVT (clib_bihash_kv) * key_result)
310 hash = BV (clib_bihash_hash) (key_result);
316 (
BVT (clib_bihash) *
h,
u64 hash)
319 BVT (clib_bihash_bucket) * b;
321 bucket_index = hash & (h->nbuckets - 1);
322 b = &h->buckets[bucket_index];
328 (
BVT (clib_bihash) *
h,
u64 hash)
331 BVT (clib_bihash_value) *
v;
332 BVT (clib_bihash_bucket) * b;
334 bucket_index = hash & (h->nbuckets - 1);
335 b = &h->buckets[bucket_index];
340 hash >>= h->log2_nbuckets;
343 v += (b->linear_search == 0) ? hash & ((1 << b->log2_pages) - 1) : 0;
348 static inline int BV (clib_bihash_search_inline_2_with_hash)
349 (
BVT (clib_bihash) *
h,
350 u64 hash,
BVT (clib_bihash_kv) * search_key,
BVT (clib_bihash_kv) * valuep)
353 BVT (clib_bihash_value) *
v;
354 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;
377 v += (b->linear_search == 0) ? hash & ((1 << b->log2_pages) - 1) : 0;
379 limit <<= b->log2_pages;
381 for (i = 0; i < limit; i++)
383 if (BV (clib_bihash_key_compare) (
v->kvp[
i].key, search_key->key))
393 (
BVT (clib_bihash) *
h,
394 BVT (clib_bihash_kv) * search_key,
BVT (clib_bihash_kv) * valuep)
398 hash = BV (clib_bihash_hash) (search_key);
400 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_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.
void clib_bihash_foreach_key_value_pair(clib_bihash *h, void *callback, void *arg)
Visit active (key,value) pairs in a bi-hash table.
#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.
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.
#define CLIB_CACHE_LINE_BYTES
#define STATIC_ASSERT_SIZEOF(d, s)