X-Git-Url: https://git.liburcu.org/?p=urcu.git;a=blobdiff_plain;f=rculfhash.c;h=0d8c5d6150ae9fa9eecc05d46b96e2ff4e6ef44c;hp=720fd0151e20ce70b31b4d5a4012f4ae2d123592;hb=9b35f1e4c8561fd8937ab394e65cc9b230ea854d;hpb=273399de2e11da5cfea7b412a4bdd904467e9126 diff --git a/rculfhash.c b/rculfhash.c index 720fd01..0d8c5d6 100644 --- a/rculfhash.c +++ b/rculfhash.c @@ -217,16 +217,14 @@ void _ht_gc_bucket(struct rcu_ht_node *dummy, struct rcu_ht_node *node) /* We can always skip the dummy node initially */ iter = rcu_dereference(iter_prev->next); assert(iter_prev->reverse_hash <= node->reverse_hash); - if (unlikely(!iter)) - return; for (;;) { + if (unlikely(!iter)) + return; if (clear_flag(iter)->reverse_hash > node->reverse_hash) return; next = rcu_dereference(clear_flag(iter)->next); if (is_removed(next)) break; - if (unlikely(!next)) - return; iter_prev = iter; iter = next; } @@ -261,7 +259,7 @@ int _ht_add(struct rcu_ht *ht, struct rcu_table *t, struct rcu_ht_node *node, goto insert; next = rcu_dereference(clear_flag(iter)->next); if (is_removed(next)) - goto gc; + goto gc_node; /* Only account for identical reverse hash once */ if (iter_prev->reverse_hash != clear_flag(iter)->reverse_hash) check_resize(ht, t, ++chain_len); @@ -278,10 +276,9 @@ int _ht_add(struct rcu_ht *ht, struct rcu_table *t, struct rcu_ht_node *node, continue; /* retry */ else goto gc_end; - gc: - /* Garbage collect logically removed nodes in the bucket */ - dummy = rcu_dereference(t->tbl[node->hash & (t->size - 1)]); - _ht_gc_bucket(dummy, node); + gc_node: + assert(!is_removed(iter)); + (void) uatomic_cmpxchg(&iter_prev->next, iter, clear_flag(next)); /* retry */ } gc_end: