*/
#include <urcu/rculfhash.h>
+#include <stdio.h>
#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)
* 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 {
+ /* 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
+ * mutex, because we use synchronize_rcu within this mutex critical
+ * section, which waits on read-side critical sections, and could
+ * therefore cause grace-period deadlock if we hold off RCU G.P.
+ * completion.
+ */
+ pthread_mutex_t resize_mutex; /* resize mutex: add/del mutex */
+ pthread_attr_t *resize_attr; /* Resize threads attributes */
+ unsigned int in_progress_resize, in_progress_destroy;
+ unsigned long resize_target;
+ int resize_initiated;
+
+ /*
+ * Variables needed for add and remove fast-paths.
+ */
+ int flags;
+ unsigned long min_alloc_buckets_order;
+ unsigned long min_nr_alloc_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.
struct cds_lfht_node *tbl_mmap;
};
/*
- * 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);
- /*
- * End of variables needed for lookup fast-path.
- */
-
- struct ht_items_count *split_count; /* split item count */
- /*
- * End of variables needed for add/remove fast-path.
+ * End of variables needed for the lookup, add and remove
+ * fast-paths.
*/
-
- /* Initial configuration items */
- int flags;
- unsigned long min_alloc_buckets_order;
- unsigned long min_nr_alloc_buckets;
- 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
- * mutex, because we use synchronize_rcu within this mutex critical
- * section, which waits on read-side critical sections, and could
- * therefore cause grace-period deadlock if we hold off RCU G.P.
- * completion.
- */
- pthread_mutex_t resize_mutex; /* resize mutex: add/del mutex */
- pthread_attr_t *resize_attr; /* Resize threads attributes */
- unsigned int in_progress_resize, in_progress_destroy;
- unsigned long resize_target;
- int resize_initiated;
};
-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) \
#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 */