X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=urcu%2Frcuja.h;h=7546332d5ea2a2638a7543e23dc742318f39471a;hb=c01cfe733a13947b5d8ba49c8529b1f691558c9d;hp=2a0de286256b46bb12dabe07d95c85151ed16ccf;hpb=d8536f92244c14455fb90fdd06cb4628d65acf32;p=userspace-rcu.git diff --git a/urcu/rcuja.h b/urcu/rcuja.h index 2a0de28..7546332 100644 --- a/urcu/rcuja.h +++ b/urcu/rcuja.h @@ -71,17 +71,32 @@ void cds_ja_node_init(struct cds_ja_node *node) struct cds_ja_node *cds_ja_lookup(struct cds_ja *ja, uint64_t key); /* - * cds_ja_lookup_lower_equal - look up first node with key <= @key. + * cds_ja_lookup_below_equal - look up first node with key <= @key. * @ja: the Judy array. * @key: key to look up. + * @result_key: key found. * * Returns the first node of a duplicate chain if a node is present in - * the tree which has a key lower or equal to @key, else returns NULL. + * the tree which has a key below or equal to @key, else returns NULL. * A RCU read-side lock should be held across call to this function and * use of its return value. */ -struct cds_ja_node *cds_ja_lookup_lower_equal(struct cds_ja *ja, - uint64_t key); +struct cds_ja_node *cds_ja_lookup_below_equal(struct cds_ja *ja, + uint64_t key, uint64_t *result_key); + +/* + * cds_ja_lookup_above_equal - look up first node with key >= @key. + * @ja: the Judy array. + * @key: key to look up. + * @result_key: key found. + * + * Returns the first node of a duplicate chain if a node is present in + * the tree which has a key above or equal to @key, else returns NULL. + * A RCU read-side lock should be held across call to this function and + * use of its return value. + */ +struct cds_ja_node *cds_ja_lookup_above_equal(struct cds_ja *ja, + uint64_t key, uint64_t *result_key); /* * cds_ja_add - Add @node at @key, allowing duplicates. @@ -143,21 +158,73 @@ struct cds_ja *cds_ja_new(unsigned int key_bits) * @rcu_free_node_cb: callback performing memory free of leftover nodes. * * Returns 0 on success, negative error value on error. - * The @rcu_free_node_cb callback should internally wait for a grace - * period before freeing the node. + * There should be no more concurrent add, delete, nor look-up performed + * on the Judy array while it is being destroyed (ensured by the caller). + * There is no need for the @rcu_free_node_cb callback to wait for grace + * periods, since there are no more concurrent users of the Judy array. + * RCU read-side lock should _not_ be held when calling this function, + * however, QSBR threads need to be online. */ int cds_ja_destroy(struct cds_ja *ja, - void (*rcu_free_node_cb)(struct cds_ja_node *node)); + void (*free_node_cb)(struct cds_ja_node *node)); /* + * cds_ja_for_each_duplicate_rcu: Iterate through duplicates. + * @pos: struct cds_ja_node *, start of duplicate list and loop cursor. + * * Iterate through duplicates returned by cds_ja_lookup*() * This must be done while rcu_read_lock() is held. * Receives a struct cds_ja_node * as parameter, which is used as start * of duplicate list and loop cursor. + * _NOT_ safe against node removal within iteration. */ #define cds_ja_for_each_duplicate_rcu(pos) \ for (; (pos) != NULL; (pos) = rcu_dereference((pos)->next)) +/* + * cds_ja_for_each_duplicate_safe_rcu: Iterate through duplicates. + * @pos: struct cds_ja_node *, start of duplicate list and loop cursor. + * @p: struct cds_ja_node *, temporary pointer to next. + * + * Iterate through duplicates returned by cds_ja_lookup*() + * This must be done while rcu_read_lock() is held. + * Safe against node removal within iteration. + */ +#define cds_ja_for_each_duplicate_safe_rcu(pos, p) \ + for (; (pos) != NULL ? \ + ((p) = rcu_dereference((pos)->next), 1) : 0; \ + (pos) = (p)) + +/* + * cds_ja_for_each_key_rcu: Iterate over all keys in ascending order. + * @ja: Judy array on which iteration should be done. + * @key: Key cursor, needs to be a uint64_t. + * @pos: struct cds_ja_node *, used as loop cursor. + * + * Iterate over all keys of a RCU Judy array (_not_ duplicates) in + * ascending order. + * This must be done while rcu_read_lock() is held. + * Safe against node removal during iteration. + */ +#define cds_ja_for_each_key_rcu(ja, key, pos) \ + for ((key) = 0; \ + ((pos) = cds_ja_lookup_above_equal(ja, key, &(key))); ) + +/* + * cds_ja_for_each_key_prev_rcu: Iterate over all keys in descending order. + * @ja: Judy array on which iteration should be done. + * @key: Key cursor, needs to be a uint64_t. + * @pos: struct cds_ja_node *, used as loop cursor. + * + * Iterate over all keys of a RCU Judy array (_not_ duplicates) in + * descending order. + * This must be done while rcu_read_lock() is held. + * Safe against node removal during iteration. + */ +#define cds_ja_for_each_key_prev_rcu(ja, key, pos) \ + for ((key) = UINT64_MAX; \ + ((pos) = cds_ja_lookup_below_equal(ja, key, &(key))); ) + #ifdef __cplusplus } #endif