__attribute__((visibility("protected")))
void rcuja_free_all_children(struct cds_ja_shadow_node *shadow_node,
- struct cds_ja_inode_flag *node_flag,
- void (*free_node_cb)(struct cds_ja_node *node));
+ struct cds_ja_inode_flag *node_flag);
__attribute__((visibility("protected")))
struct cds_ja_shadow_node *rcuja_shadow_lookup_lock(struct cds_lfht *ht,
__attribute__((visibility("protected")))
void rcuja_shadow_prune(struct cds_lfht *ht,
- unsigned int flags,
- void (*free_node_cb)(struct cds_ja_node *node));
+ unsigned int flags);
__attribute__((visibility("protected")))
struct cds_lfht *rcuja_create_ht(const struct rcu_flavor_struct *flavor);
* Receives a struct cds_ja_node * as parameter, which is used as start
* of duplicate list and loop cursor.
*/
-#define cds_ja_for_each_duplicate(pos) \
- for (; (pos) != NULL; (pos) = (pos)->next)
-
-/*
- * Iterate through duplicates returned by cds_ja_lookup*()
- * Safe against removal of entries during traversal.
- */
-#define cds_ja_for_each_duplicate_safe(_pos, _next) \
- for (; (_pos) != NULL ? ((_next) = (_pos)->next, 1) : 0; \
- (_pos) = (_next))
+#define cds_ja_for_each_duplicate(pos) \
+ for (; (pos) != NULL; (pos) = (pos)->next)
//#define DEBUG
*/
__attribute__((visibility("protected")))
void rcuja_shadow_prune(struct cds_lfht *ht,
- unsigned int flags,
- void (*free_node_cb)(struct cds_ja_node *node))
+ unsigned int flags)
{
const struct rcu_flavor_struct *flavor;
struct cds_ja_shadow_node *shadow_node;
goto unlock;
if ((flags & RCUJA_SHADOW_CLEAR_FREE_NODE)
&& shadow_node->level) {
- if (shadow_node->level == shadow_node->ja->tree_depth - 1) {
- rcuja_free_all_children(shadow_node,
- shadow_node->node_flag,
- free_node_cb);
- }
if (flags & RCUJA_SHADOW_CLEAR_FREE_LOCK) {
flavor->update_call_rcu(&shadow_node->head,
free_shadow_node_and_node_and_lock);
return NULL;
}
-/*
- * Called from RCU read-side CS.
- */
-__attribute__((visibility("protected")))
-void rcuja_free_all_children(struct cds_ja_shadow_node *shadow_node,
- struct cds_ja_inode_flag *node_flag,
- void (*rcu_free_node)(struct cds_ja_node *node))
-{
- unsigned int type_index;
- struct cds_ja_inode *node;
- const struct cds_ja_type *type;
-
- node = ja_node_ptr(node_flag);
- assert(node != NULL);
- type_index = ja_node_type(node_flag);
- type = &ja_types[type_index];
-
- switch (type->type_class) {
- case RCU_JA_LINEAR:
- {
- uint8_t nr_child =
- ja_linear_node_get_nr_child(type, node);
- unsigned int i;
-
- for (i = 0; i < nr_child; i++) {
- struct cds_ja_inode_flag *iter;
- struct cds_ja_node *node_iter, *n;
- uint8_t v;
-
- ja_linear_node_get_ith_pos(type, node, i, &v, &iter);
- node_iter = (struct cds_ja_node *) iter;
- cds_ja_for_each_duplicate_safe(node_iter, n) {
- rcu_free_node(node_iter);
- }
- }
- break;
- }
- case RCU_JA_POOL:
- {
- unsigned int pool_nr;
-
- for (pool_nr = 0; pool_nr < (1U << type->nr_pool_order); pool_nr++) {
- struct cds_ja_inode *pool =
- ja_pool_node_get_ith_pool(type, node, pool_nr);
- uint8_t nr_child =
- ja_linear_node_get_nr_child(type, pool);
- unsigned int j;
-
- for (j = 0; j < nr_child; j++) {
- struct cds_ja_inode_flag *iter;
- struct cds_ja_node *node_iter, *n;
- uint8_t v;
-
- ja_linear_node_get_ith_pos(type, pool, j, &v, &iter);
- node_iter = (struct cds_ja_node *) iter;
- cds_ja_for_each_duplicate_safe(node_iter, n) {
- rcu_free_node(node_iter);
- }
- }
- }
- break;
- }
- case RCU_JA_NULL:
- break;
- case RCU_JA_PIGEON:
- {
- unsigned int i;
-
- for (i = 0; i < JA_ENTRY_PER_NODE; i++) {
- struct cds_ja_inode_flag *iter;
- struct cds_ja_node *node_iter, *n;
-
- iter = ja_pigeon_node_get_ith_pos(type, node, i);
- node_iter = (struct cds_ja_node *) iter;
- cds_ja_for_each_duplicate_safe(node_iter, n) {
- rcu_free_node(node_iter);
- }
- }
- break;
- }
- default:
- assert(0);
- }
-}
-
static
void print_debug_fallback_distribution(struct cds_ja *ja)
{
* on the Judy array while it is being destroyed (ensured by the
* caller).
*/
-int cds_ja_destroy(struct cds_ja *ja,
- void (*free_node_cb)(struct cds_ja_node *node))
+int cds_ja_destroy(struct cds_ja *ja)
{
const struct rcu_flavor_struct *flavor;
int ret;
flavor = cds_lfht_rcu_flavor(ja->ht);
rcuja_shadow_prune(ja->ht,
- RCUJA_SHADOW_CLEAR_FREE_NODE | RCUJA_SHADOW_CLEAR_FREE_LOCK,
- free_node_cb);
+ RCUJA_SHADOW_CLEAR_FREE_NODE | RCUJA_SHADOW_CLEAR_FREE_LOCK);
flavor->thread_offline();
ret = rcuja_delete_ht(ja->ht);
if (ret)
return -1;
}
- ret = cds_ja_destroy(test_ja, free_node);
+ ret = cds_ja_destroy(test_ja);
if (ret) {
fprintf(stderr, "Error destroying judy array\n");
return -1;
return -1;
}
- ret = cds_ja_destroy(test_ja, free_node);
+ ret = cds_ja_destroy(test_ja);
if (ret) {
fprintf(stderr, "Error destroying judy array\n");
return -1;
return -1;
}
- ret = cds_ja_destroy(test_ja, free_node);
+ ret = cds_ja_destroy(test_ja);
if (ret) {
fprintf(stderr, "Error destroying judy array\n");
return -1;
return -1;
}
- ret = cds_ja_destroy(test_ja, free_node);
+ ret = cds_ja_destroy(test_ja);
if (ret) {
fprintf(stderr, "Error destroying judy array\n");
goto end;
/*
* cds_ja_destroy - Destroy a Judy array.
* @ja: the Judy array.
- * @rcu_free_node_cb: callback performing memory free of leftover nodes.
*
* Returns 0 on success, negative error value on error.
* 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 (*free_node_cb)(struct cds_ja_node *node));
+int cds_ja_destroy(struct cds_ja *ja);
/*
* cds_ja_for_each_duplicate_rcu: Iterate through duplicates.
* of duplicate list and loop cursor.
* _NOT_ safe against node removal within iteration.
*/
-#define cds_ja_for_each_duplicate_rcu(pos) \
+#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.
+ * cds_ja_for_each_duplicate_safe: 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.
+ * Iterate through duplicates returned by cds_ja_lookup*().
* Safe against node removal within iteration.
+ * This must be done while rcu_read_lock() is held.
*/
#define cds_ja_for_each_duplicate_safe_rcu(pos, p) \
for (; (pos) != NULL ? \