rcuja: implement add unique
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 30 May 2013 20:34:59 +0000 (16:34 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 30 May 2013 20:34:59 +0000 (16:34 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
rcuja/rcuja.c
tests/test_urcu_ja.c
urcu/rcuja.h

index e5145ea36a3b22dbec54cd4a45eeefe7334e343a..84c1fb73c26afdc3bc09b0bd037edf6a728d4027 100644 (file)
@@ -1793,8 +1793,10 @@ end:
        return ret;
 }
 
-int cds_ja_add(struct cds_ja *ja, uint64_t key,
-               struct cds_ja_node *new_node)
+static
+int _cds_ja_add(struct cds_ja *ja, uint64_t key,
+               struct cds_ja_node *new_node,
+               struct cds_ja_node **unique_node_ret)
 {
        unsigned int tree_depth, i;
        struct cds_ja_inode_flag *attach_node_flag,
@@ -1847,6 +1849,7 @@ retry:
        if (!ja_node_ptr(node_flag)) {
                dbg_printf("cds_ja_add NULL parent2_node_flag %p parent_node_flag %p node_flag_ptr %p node_flag %p\n",
                                parent2_node_flag, parent_node_flag, node_flag_ptr, node_flag);
+
                attach_node_flag = parent_node_flag;
                attach_node_flag_ptr = parent_node_flag_ptr;
                parent_attach_node_flag = parent2_node_flag;
@@ -1858,8 +1861,14 @@ retry:
                                node_flag,
                                key, i, new_node);
        } else {
+               if (unique_node_ret) {
+                       *unique_node_ret = (struct cds_ja_node *) ja_node_ptr(node_flag);
+                       return -EEXIST;
+               }
+
                dbg_printf("cds_ja_add duplicate parent2_node_flag %p parent_node_flag %p node_flag_ptr %p node_flag %p\n",
                                parent2_node_flag, parent_node_flag, node_flag_ptr, node_flag);
+
                attach_node_flag = node_flag;
                attach_node_flag_ptr = node_flag_ptr;
                parent_attach_node_flag = parent_node_flag;
@@ -1876,6 +1885,25 @@ retry:
        return ret;
 }
 
+int cds_ja_add(struct cds_ja *ja, uint64_t key,
+               struct cds_ja_node *new_node)
+{
+       return _cds_ja_add(ja, key, new_node, NULL);
+}
+
+struct cds_ja_node *cds_ja_add_unique(struct cds_ja *ja, uint64_t key,
+               struct cds_ja_node *new_node)
+{
+       int ret;
+       struct cds_ja_node *ret_node;
+
+       ret = _cds_ja_add(ja, key, new_node, &ret_node);
+       if (ret == -EEXIST)
+               return ret_node;
+       else
+               return new_node;
+}
+
 /*
  * Note: there is no need to lookup the pointer address associated with
  * each node's nth item after taking the lock: it's already been done by
@@ -2312,7 +2340,7 @@ void rcuja_free_all_children(struct cds_ja_shadow_node *shadow_node,
                                struct cds_hlist_node *pos, *tmp;
                                uint8_t v;
 
-                               ja_linear_node_get_ith_pos(type, node, j, &v, &iter);
+                               ja_linear_node_get_ith_pos(type, pool, j, &v, &iter);
                                if (!iter)
                                        continue;
                                head.next = (struct cds_hlist_node *) iter;
index bad6784a446db3ecb1857de5c459dc93ffd66d13..af6ba08f133fd3161a2b013518a167a01f6567dc 100644 (file)
@@ -666,19 +666,20 @@ void *test_ja_rw_thr_writer(void *_count)
                if ((addremove == AR_ADD)
                                || (addremove == AR_RANDOM && is_add())) {
                        struct ja_test_node *node = malloc(sizeof(*node));
+                       struct cds_ja_node *ret_node;
 
                        /* note: only inserting ulong keys */
                        key = ((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % write_pool_size) + write_pool_offset;
                        key *= key_mul;
                        ja_test_node_init(node, key);
                        rcu_read_lock();
-                       ret = cds_ja_add(test_ja, key, &node->node);
-                       URCU_TLS(nr_add)++;
+                       ret_node = cds_ja_add_unique(test_ja, key, &node->node);
                        rcu_read_unlock();
-                       if (ret) {
-                               fprintf(stderr, "Error (%d) adding node %" PRIu64 "\n",
-                                       ret, key);
-                               assert(0);
+                       if (ret_node != &node->node) {
+                               free(node);
+                               URCU_TLS(nr_addexist)++;
+                       } else {
+                               URCU_TLS(nr_add)++;
                        }
                } else {
                        struct ja_test_node *node;
index 9a006a395bcc31a3748acd42e134036a5a5e4254..0ab05183720a3dbdaa8c46057f4d8e41bf0317ee 100644 (file)
@@ -62,6 +62,9 @@ struct cds_hlist_head cds_ja_lookup(struct cds_ja *ja, uint64_t key);
 int cds_ja_add(struct cds_ja *ja, uint64_t key,
                struct cds_ja_node *new_node);
 
+struct cds_ja_node *cds_ja_add_unique(struct cds_ja *ja, uint64_t key,
+               struct cds_ja_node *new_node);
+
 int cds_ja_del(struct cds_ja *ja, uint64_t key,
                struct cds_ja_node *node);
 
This page took 0.028094 seconds and 4 git commands to generate.