X-Git-Url: https://git.liburcu.org/?p=urcu.git;a=blobdiff_plain;f=rculfhash-internal.h;h=d7cec95a10e286f4693c91925e61441146196ebe;hp=f7c659044acceb36829c424ca594d3f3aed1f02d;hb=b83b3590caf8ddd0fb1393b0d8378f916c8bf831;hpb=308d1cb3650b63d373e60eef0582d6e238b0d2d0 diff --git a/rculfhash-internal.h b/rculfhash-internal.h index f7c6590..d7cec95 100644 --- a/rculfhash-internal.h +++ b/rculfhash-internal.h @@ -25,11 +25,17 @@ */ #include +#include #ifdef DEBUG #define dbg_printf(fmt, args...) printf("[debug rculfhash] " fmt, ## args) #else -#define dbg_printf(fmt, args...) +#define dbg_printf(fmt, args...) \ +do { \ + /* do nothing but check printf format */ \ + if (0) \ + printf("[debug rculfhash] " fmt, ## args); \ +} while (0) #endif #if (CAA_BITS_PER_LONG == 32) @@ -54,10 +60,18 @@ struct ht_items_count; * cds_lfht: Top-level data structure representing a lock-free hash * table. Defined in the implementation file to make it be an opaque * cookie to users. + * + * The fields used in fast-paths are placed near the end of the + * structure, because we need to have a variable-sized union to contain + * the mm plugin fields, which are used in the fast path. */ struct cds_lfht { - unsigned long size; /* always a power of 2, shared (RCU) */ - int flags; + /* Initial configuration items */ + unsigned long max_nr_buckets; + const struct cds_lfht_mm_type *mm; /* memory management plugin */ + const struct rcu_flavor_struct *flavor; /* RCU flavor */ + + long count; /* global approximate item count */ /* * We need to put the work threads offline (QSBR) when taking this @@ -71,21 +85,29 @@ struct cds_lfht { unsigned int in_progress_resize, in_progress_destroy; unsigned long resize_target; int resize_initiated; - const struct rcu_flavor_struct *flavor; - - long count; /* global approximate item count */ - struct ht_items_count *split_count; /* split item count */ - - /* memory management related fields are located at the end */ - const struct cds_lfht_mm_type *mm; + /* + * Variables needed for add and remove fast-paths. + */ + int flags; unsigned long min_alloc_buckets_order; unsigned long min_nr_alloc_buckets; - unsigned long max_nr_buckets; + struct ht_items_count *split_count; /* split item count */ + /* + * Variables needed for the lookup, add and remove fast-paths. + */ + unsigned long size; /* always a power of 2, shared (RCU) */ + /* + * bucket_at pointer is kept here to skip the extra level of + * dereference needed to get to "mm" (this is a fast-path). + */ struct cds_lfht_node *(*bucket_at)(struct cds_lfht *ht, unsigned long index); - + /* + * Dynamic length "tbl_chunk" needs to be at the end of + * cds_lfht. + */ union { /* * Contains the per order-index-level bucket node table. @@ -108,11 +130,21 @@ struct cds_lfht { * memory addressing. */ struct cds_lfht_node *tbl_chunk[0]; + + /* + * Memory mapping with room for all possible buckets. + * Their memory is allocated when needed. + */ + struct cds_lfht_node *tbl_mmap; }; + /* + * End of variables needed for the lookup, add and remove + * fast-paths. + */ }; -extern unsigned int fls_ulong(unsigned long x); -extern int get_count_order_ulong(unsigned long x); +extern unsigned int cds_lfht_fls_ulong(unsigned long x); +extern int cds_lfht_get_count_order_ulong(unsigned long x); #ifdef POISON_FREE #define poison_free(ptr) \ @@ -126,4 +158,26 @@ extern int get_count_order_ulong(unsigned long x); #define poison_free(ptr) free(ptr) #endif +static inline +struct cds_lfht *__default_alloc_cds_lfht( + const struct cds_lfht_mm_type *mm, + unsigned long cds_lfht_size, + unsigned long min_nr_alloc_buckets, + unsigned long max_nr_buckets) +{ + struct cds_lfht *ht; + + ht = calloc(1, cds_lfht_size); + assert(ht); + + ht->mm = mm; + ht->bucket_at = mm->bucket_at; + ht->min_nr_alloc_buckets = min_nr_alloc_buckets; + ht->min_alloc_buckets_order = + cds_lfht_get_count_order_ulong(min_nr_alloc_buckets); + ht->max_nr_buckets = max_nr_buckets; + + return ht; +} + #endif /* _URCU_RCULFHASH_INTERNAL_H */