From 18117871130163ec2b2fc73fda288b9ba26cd435 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Thu, 7 Jul 2011 11:48:34 -0400 Subject: [PATCH] rculfhash: update add_unique api Signed-off-by: Mathieu Desnoyers --- rculfhash.c | 16 +++++++++------- tests/test_urcu_hash.c | 7 ++++--- urcu/rculfhash.h | 9 +++++++-- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/rculfhash.c b/rculfhash.c index 1ccd3f1..556ec36 100644 --- a/rculfhash.c +++ b/rculfhash.c @@ -234,14 +234,16 @@ void _ht_gc_bucket(struct rcu_ht_node *dummy, struct rcu_ht_node *node) } static -int _ht_add(struct rcu_ht *ht, struct rcu_table *t, struct rcu_ht_node *node, - int unique) +struct rcu_ht_node *_ht_add(struct rcu_ht *ht, struct rcu_table *t, + struct rcu_ht_node *node, int unique) { struct rcu_ht_node *iter_prev, *dummy, *iter, *next; unsigned long hash; - if (!t->size) - return 0; + if (!t->size) { + assert(node->dummy); + return node; /* Initial first add (head) */ + } hash = bit_reverse_ulong(node->reverse_hash); for (;;) { uint32_t chain_len = 0; @@ -267,7 +269,7 @@ int _ht_add(struct rcu_ht *ht, struct rcu_table *t, struct rcu_ht_node *node, && !ht->compare_fct(node->key, node->key_len, clear_flag(iter)->key, clear_flag(iter)->key_len)) - return -EEXIST; + return clear_flag(iter); /* Only account for identical reverse hash once */ if (iter_prev->reverse_hash != clear_flag(iter)->reverse_hash) check_resize(ht, t, ++chain_len); @@ -293,7 +295,7 @@ gc_end: /* Garbage collect logically removed nodes in the bucket */ dummy = rcu_dereference(t->tbl[hash & (t->size - 1)]); _ht_gc_bucket(dummy, node); - return 0; + return node; } static @@ -423,7 +425,7 @@ void ht_add(struct rcu_ht *ht, struct rcu_ht_node *node) (void) _ht_add(ht, t, node, 0); } -int ht_add_unique(struct rcu_ht *ht, struct rcu_ht_node *node) +struct rcu_ht_node *ht_add_unique(struct rcu_ht *ht, struct rcu_ht_node *node) { struct rcu_table *t; unsigned long hash; diff --git a/tests/test_urcu_hash.c b/tests/test_urcu_hash.c index e8c51d8..16374d9 100644 --- a/tests/test_urcu_hash.c +++ b/tests/test_urcu_hash.c @@ -387,7 +387,7 @@ void free_node_cb(struct rcu_head *head) void *thr_writer(void *_count) { - struct rcu_ht_node *node; + struct rcu_ht_node *node, *ret_node; struct wr_count *count = _count; int ret; @@ -410,9 +410,9 @@ void *thr_writer(void *_count) ht_node_init(node, (void *)(unsigned long)(rand_r(&rand_lookup) % RAND_POOL), sizeof(void *)); - ret = ht_add_unique(test_ht, node); + ret_node = ht_add_unique(test_ht, node); rcu_read_unlock(); - if (ret) { + if (ret_node != node) { free(node); nr_addexist++; } else @@ -569,6 +569,7 @@ int main(int argc, char **argv) count_writer = malloc(sizeof(*count_writer) * nr_writers); test_ht = ht_new(test_hash, test_compare, 0x42UL, HASH_SIZE, call_rcu); + next_aff = 0; for (i = 0; i < nr_readers; i++) { diff --git a/urcu/rculfhash.h b/urcu/rculfhash.h index bec7776..6bb1ccf 100644 --- a/urcu/rculfhash.h +++ b/urcu/rculfhash.h @@ -58,8 +58,13 @@ struct rcu_ht_node *ht_lookup(struct rcu_ht *ht, void *key, size_t key_len); /* Call with rcu_read_lock held. */ void ht_add(struct rcu_ht *ht, struct rcu_ht_node *node); -/* Call with rcu_read_lock held. */ -int ht_add_unique(struct rcu_ht *ht, struct rcu_ht_node *node); +/* + * Call with rcu_read_lock held. + * Returns the node added upon success. + * Returns the unique node already present upon failure. If ht_add_unique fails, + * the node passed as parameter should be freed by the caller. + */ +struct rcu_ht_node *ht_add_unique(struct rcu_ht *ht, struct rcu_ht_node *node); /* Call with rcu_read_lock held. */ int ht_remove(struct rcu_ht *ht, struct rcu_ht_node *node); -- 2.34.1