rcuja: test duplicate node/key support
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sun, 26 Aug 2012 00:57:59 +0000 (20:57 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 14 May 2013 14:22:23 +0000 (16:22 +0200)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
tests/test_urcu_ja.c

index dde3572faf76a0201a9bf4d1430cbab77a62e37a..5244754d7b364b0c34af5d924e215e0e1a85e60c 100644 (file)
@@ -365,12 +365,14 @@ int test_16bit_key(void)
        return 0;
 }
 
+/*
+ * nr_dup is number of nodes per key.
+ */
 static
-int test_sparse_key(unsigned int bits)
+int test_sparse_key(unsigned int bits, int nr_dup)
 {
-       int ret;
        uint64_t key, max_key;
-       int zerocount;
+       int zerocount, i, ret;
 
        if (bits == 64)
                max_key = UINT64_MAX;
@@ -387,22 +389,24 @@ int test_sparse_key(unsigned int bits)
 
        /* Add keys */
        printf("Test #1: add keys (%u-bit).\n", bits);
-       zerocount = 0;
-       for (key = 0; key <= max_key && (key != 0 || zerocount < 1); key += 1ULL << (bits - 8)) {
-               struct ja_test_node *node =
-                       calloc(sizeof(*node), 1);
+       for (i = 0; i < nr_dup; i++) {
+               zerocount = 0;
+               for (key = 0; key <= max_key && (key != 0 || zerocount < 1); key += 1ULL << (bits - 8)) {
+                       struct ja_test_node *node =
+                               calloc(sizeof(*node), 1);
 
-               ja_test_node_init(node, key);
-               rcu_read_lock();
-               ret = cds_ja_add(test_ja, key, &node->node);
-               rcu_read_unlock();
-               if (ret) {
-                       fprintf(stderr, "Error (%d) adding node %" PRIu64 "\n",
-                               ret, key);
-                       assert(0);
+                       ja_test_node_init(node, key);
+                       rcu_read_lock();
+                       ret = cds_ja_add(test_ja, key, &node->node);
+                       rcu_read_unlock();
+                       if (ret) {
+                               fprintf(stderr, "Error (%d) adding node %" PRIu64 "\n",
+                                       ret, key);
+                               assert(0);
+                       }
+                       if (key == 0)
+                               zerocount++;
                }
-               if (key == 0)
-                       zerocount++;
        }
        printf("OK\n");
 
@@ -410,6 +414,9 @@ int test_sparse_key(unsigned int bits)
        zerocount = 0;
        for (key = 0; key <= max_key && (key != 0 || zerocount < 1); key += 1ULL << (bits - 8)) {
                struct cds_hlist_head head;
+               struct ja_test_node *node;
+               struct cds_hlist_node *pos;
+               int count = 0;
 
                rcu_read_lock();
                head = cds_ja_lookup(test_ja, key);
@@ -417,6 +424,12 @@ int test_sparse_key(unsigned int bits)
                        fprintf(stderr, "Error lookup node %" PRIu64 "\n", key);
                        assert(0);
                }
+               cds_hlist_for_each_entry_rcu(node, pos, &head, node.list) {
+                       count++;
+               }
+               if (count != nr_dup) {
+                       fprintf(stderr, "Unexpected number of match for key %" PRIu64 ", expected %d, got %d.\n", key, nr_dup, count);
+               }
                rcu_read_unlock();
                if (key == 0)
                        zerocount++;
@@ -447,20 +460,33 @@ int test_sparse_key(unsigned int bits)
        for (key = 0; key <= max_key && (key != 0 || zerocount < 1); key += 1ULL << (bits - 8)) {
                struct cds_hlist_head head;
                struct ja_test_node *node;
+               struct cds_hlist_node *pos;
+               int count = 0;
 
                rcu_read_lock();
                head = cds_ja_lookup(test_ja, key);
-               node = cds_hlist_first_entry_rcu(&head, struct ja_test_node, node.list);
-               if (!node) {
-                       fprintf(stderr, "Error lookup node %" PRIu64 "\n", key);
-                       assert(0);
-               }
-               ret = cds_ja_del(test_ja, key, &node->node);
-               if (ret) {
-                       fprintf(stderr, "Error (%d) removing node %" PRIu64 "\n", ret, key);
-                       assert(0);
+
+
+               cds_hlist_for_each_entry_rcu(node, pos, &head, node.list) {
+                       struct cds_hlist_head testhead;
+
+                       count++;
+                       if (!node) {
+                               fprintf(stderr, "Error lookup node %" PRIu64 "\n", key);
+                               assert(0);
+                       }
+                       ret = cds_ja_del(test_ja, key, &node->node);
+                       if (ret) {
+                               fprintf(stderr, "Error (%d) removing node %" PRIu64 "\n", ret, key);
+                               assert(0);
+                       }
+                       call_rcu(&node->node.head, free_node_cb);
+                       testhead = cds_ja_lookup(test_ja, key);
+                       if (count < nr_dup && cds_hlist_empty(&testhead)) {
+                               fprintf(stderr, "Error: no node found after deletion of some nodes of a key\n");
+                               assert(0);
+                       }
                }
-               call_rcu(&node->node.head, free_node_cb);
                head = cds_ja_lookup(test_ja, key);
                if (!cds_hlist_empty(&head)) {
                        fprintf(stderr, "Error lookup %" PRIu64 ": %p (after delete) failed. Node is not expected.\n", key, head.next);
@@ -492,7 +518,7 @@ int main(int argc, char **argv)
        struct wr_count *count_writer;
        unsigned long long tot_reads = 0, tot_writes = 0,
                tot_add = 0, tot_add_exist = 0, tot_remove = 0;
-       int i, a, ret;
+       int i, j, a, ret;
        unsigned int remain;
        uint64_t key;
 
@@ -630,29 +656,17 @@ int main(int argc, char **argv)
        }
        rcu_quiescent_state();
 
-       ret = test_sparse_key(8);
-       if (ret) {
-               return ret;
-       }
-       rcu_quiescent_state();
-
-       ret = test_sparse_key(16);
-       if (ret) {
-               return ret;
-       }
-       rcu_quiescent_state();
-
-       ret = test_sparse_key(32);
-       if (ret) {
-               return ret;
-       }
-       rcu_quiescent_state();
-
-       ret = test_sparse_key(64);
-       if (ret) {
-               return ret;
+       /* key bits */
+       for (i = 8; i <= 64; i *= 2) {
+               /* nr of nodes per key */
+               for (j = 1; j < 4; j++) {
+                       ret = test_sparse_key(i, j);
+                       if (ret) {
+                               return ret;
+                       }
+                       rcu_quiescent_state();
+               }
        }
-       rcu_quiescent_state();
 
        printf("Test end.\n");
        rcu_unregister_thread();
This page took 0.028139 seconds and 4 git commands to generate.