X-Git-Url: https://git.lttng.org/?p=urcu.git;a=blobdiff_plain;f=include%2Furcu%2Frculfhash.h;h=20b822fa8dddc572c5e114c31a1963f4ed499be3;hp=9934422ee9d6e1a4e737da18c73ba14c54dbbff7;hb=afa5940dbe80a259cf8bc4a99403554a3c2c9e32;hpb=6893800a4d1cc14dff0395ddcd660a5138db183d diff --git a/include/urcu/rculfhash.h b/include/urcu/rculfhash.h index 9934422..20b822f 100644 --- a/include/urcu/rculfhash.h +++ b/include/urcu/rculfhash.h @@ -23,18 +23,21 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * Include this file _after_ including your URCU flavor. + * For use with URCU_API_MAP (API mapping of liburcu), include this file + * _after_ including your URCU flavor. */ +#include #include +#include #include -#include -#include #ifdef __cplusplus extern "C" { #endif +struct cds_lfht; + /* * cds_lfht_node: Contains the next pointers and reverse-hash * value required for lookup and traversal of the hash table. @@ -65,6 +68,18 @@ struct cds_lfht_node { /* cds_lfht_iter: Used to track state while traversing a hash chain. */ struct cds_lfht_iter { struct cds_lfht_node *node, *next; + /* + * For debugging purposes, build both API users and rculfhash + * library with CDS_LFHT_ITER_DEBUG defined. This enables extra + * consistency checks for calls to a cds_lfht_next() or + * cds_lfht_next_duplicate() after the iterator has been + * re-purposed to iterate on a different hash table. This is a + * common programming mistake when performing hash table lookup + * nested in a hash table traversal. + */ +#ifdef CONFIG_CDS_LFHT_ITER_DEBUG + struct cds_lfht *lfht; +#endif }; static inline @@ -73,7 +88,7 @@ struct cds_lfht_node *cds_lfht_iter_get_node(struct cds_lfht_iter *iter) return iter->node; } -struct cds_lfht; +struct rcu_flavor_struct; /* * Caution ! @@ -127,6 +142,50 @@ struct cds_lfht *_cds_lfht_new(unsigned long init_size, const struct rcu_flavor_struct *flavor, pthread_attr_t *attr); +/* + * cds_lfht_new_flavor - allocate a hash table tied to a RCU flavor. + * @init_size: number of buckets to allocate initially. Must be power of two. + * @min_nr_alloc_buckets: the minimum number of allocated buckets. + * (must be power of two) + * @max_nr_buckets: the maximum number of hash table buckets allowed. + * (must be power of two, 0 is accepted, means + * "infinite") + * @flavor: flavor of liburcu to use to synchronize the hash table + * @flags: hash table creation flags (can be combined with bitwise or: '|'). + * 0: no flags. + * CDS_LFHT_AUTO_RESIZE: automatically resize hash table. + * CDS_LFHT_ACCOUNTING: count the number of node addition + * and removal in the table + * @attr: optional resize worker thread attributes. NULL for default. + * + * Return NULL on error. + * Note: the RCU flavor must be already included before the hash table header. + * + * The programmer is responsible for ensuring that resize operation has a + * priority equal to hash table updater threads. It should be performed by + * specifying the appropriate priority in the pthread "attr" argument, and, + * for CDS_LFHT_AUTO_RESIZE, by ensuring that call_rcu worker threads also have + * this priority level. Having lower priority for call_rcu and resize threads + * does not pose any correctness issue, but the resize operations could be + * starved by updates, thus leading to long hash table bucket chains. + * Threads calling cds_lfht_new are NOT required to be registered RCU + * read-side threads. It can be called very early. (e.g. before RCU is + * initialized) + */ +static inline +struct cds_lfht *cds_lfht_new_flavor(unsigned long init_size, + unsigned long min_nr_alloc_buckets, + unsigned long max_nr_buckets, + int flags, + const struct rcu_flavor_struct *flavor, + pthread_attr_t *attr) +{ + return _cds_lfht_new(init_size, min_nr_alloc_buckets, max_nr_buckets, + flags, NULL, flavor, attr); +} + + +#ifdef URCU_API_MAP /* * cds_lfht_new - allocate a hash table. * @init_size: number of buckets to allocate initially. Must be power of two. @@ -166,6 +225,7 @@ struct cds_lfht *cds_lfht_new(unsigned long init_size, return _cds_lfht_new(init_size, min_nr_alloc_buckets, max_nr_buckets, flags, NULL, &rcu_flavor, attr); } +#endif /* URCU_API_MAP */ /* * cds_lfht_destroy - destroy a hash table. @@ -176,10 +236,17 @@ struct cds_lfht *cds_lfht_new(unsigned long init_size, * need to be informed of the value passed to cds_lfht_new(). * * Return 0 on success, negative error value on error. - * Threads calling this API need to be registered RCU read-side threads. - * cds_lfht_destroy should *not* be called from a RCU read-side critical - * section. It should *not* be called from a call_rcu thread context - * neither. + + * Prior to liburcu 0.10: + * - Threads calling this API need to be registered RCU read-side + * threads. + * - cds_lfht_destroy should *not* be called from a RCU read-side + * critical section. It should *not* be called from a call_rcu thread + * context neither. + * + * Starting from liburcu 0.10, rculfhash implements its own worker + * thread to handle resize operations, which removes RCU requirements on + * cds_lfht_destroy. */ extern int cds_lfht_destroy(struct cds_lfht *ht, pthread_attr_t **attr); @@ -432,7 +499,7 @@ int cds_lfht_del(struct cds_lfht *ht, struct cds_lfht_node *node); * This function does not issue any memory barrier. */ extern -int cds_lfht_is_node_deleted(struct cds_lfht_node *node); +int cds_lfht_is_node_deleted(const struct cds_lfht_node *node); /* * cds_lfht_resize - Force a hash table resize