rculfhash: output approximation of number of nodes in counting
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 21 Sep 2011 13:24:17 +0000 (09:24 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 21 Sep 2011 13:24:49 +0000 (09:24 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
rculfhash.c
tests/test_urcu_hash.c
urcu/rculfhash.h

index 6045f5965c4d55207a84145031a1763a447d748c..93c2d7850fad9da9c333b47f738af08758ed62ed 100644 (file)
@@ -1446,13 +1446,25 @@ int cds_lfht_destroy(struct cds_lfht *ht, pthread_attr_t **attr)
 }
 
 void cds_lfht_count_nodes(struct cds_lfht *ht,
+               unsigned long *approx_before,
                unsigned long *count,
-               unsigned long *removed)
+               unsigned long *removed,
+               unsigned long *approx_after)
 {
        struct cds_lfht_node *node, *next;
        struct _cds_lfht_node *lookup;
        unsigned long nr_dummy = 0;
 
+       *approx_before = uatomic_read(&ht->count);
+       if (nr_cpus_mask >= 0) {
+               int i;
+
+               for (i = 0; i < nr_cpus_mask + 1; i++) {
+                       *approx_before += uatomic_read(&ht->percpu_count[i].add);
+                       *approx_before -= uatomic_read(&ht->percpu_count[i].del);
+               }
+       }
+
        *count = 0;
        *removed = 0;
 
@@ -1462,8 +1474,10 @@ void cds_lfht_count_nodes(struct cds_lfht *ht,
        do {
                next = rcu_dereference(node->p.next);
                if (is_removed(next)) {
-                       assert(!is_dummy(next));
-                       (*removed)++;
+                       if (!is_dummy(next))
+                               (*removed)++;
+                       else
+                               (nr_dummy)++;
                } else if (!is_dummy(next))
                        (*count)++;
                else
@@ -1471,6 +1485,15 @@ void cds_lfht_count_nodes(struct cds_lfht *ht,
                node = clear_flag(next);
        } while (!is_end(node));
        dbg_printf("number of dummy nodes: %lu\n", nr_dummy);
+       *approx_after = uatomic_read(&ht->count);
+       if (nr_cpus_mask >= 0) {
+               int i;
+
+               for (i = 0; i < nr_cpus_mask + 1; i++) {
+                       *approx_after += uatomic_read(&ht->percpu_count[i].add);
+                       *approx_after -= uatomic_read(&ht->percpu_count[i].del);
+               }
+       }
 }
 
 /* called with resize mutex held */
index b68db492cc0a794e0503059de006109e41e4da02..1e1cf47423942dbac3279c12e777dfc3270a7d52 100644 (file)
@@ -194,6 +194,26 @@ void sigusr1_handler(int signo)
        }
 }
 
+static
+void sigusr2_handler(int signo)
+{
+       unsigned long count, removed, approx_before, approx_after;
+
+       /* Accounting */
+       printf("Counting nodes... ");
+       fflush(stdout);
+       cds_lfht_count_nodes(test_ht, &approx_before, &count, &removed,
+                       &approx_after);
+       printf("done.\n");
+       printf("Approximation before node accounting: %lu nodes.\n",
+               approx_before);
+       printf("Accounting of nodes in the hash table: "
+               "%lu nodes + %lu logically removed.\n",
+               count, removed);
+       printf("Approximation after node accounting: %lu nodes.\n",
+               approx_after);
+}
+
 /*
  * returns 0 if test should end.
  */
@@ -623,7 +643,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;
-       unsigned long count, removed;
+       unsigned long count, removed, approx_before, approx_after;
        int i, a, ret;
        struct sigaction act;
        unsigned int remain;
@@ -765,6 +785,13 @@ int main(int argc, char **argv)
                perror("sigaction");
                return -1;
        }
+       act.sa_handler = sigusr2_handler;
+       act.sa_flags = SA_RESTART;
+       ret = sigaction(SIGUSR2, &act, NULL);
+       if (ret == -1) {
+               perror("sigaction");
+               return -1;
+       }
 
        printf_verbose("running test for %lu seconds, %u readers, %u writers.\n",
                duration, nr_readers, nr_writers);
@@ -846,11 +873,18 @@ int main(int argc, char **argv)
        }
        printf("Counting nodes... ");
        fflush(stdout);
-       cds_lfht_count_nodes(test_ht, &count, &removed);
+       cds_lfht_count_nodes(test_ht, &approx_before, &count, &removed,
+               &approx_after);
        printf("done.\n");
-       if (count || removed)
+       if (count || removed) {
+               printf("Approximation before node accounting: %lu nodes.\n",
+                       approx_before);
                printf("WARNING: nodes left in the hash table upon destroy: "
-                       "%lu nodes + %lu logically removed.\n", count, removed);
+                       "%lu nodes + %lu logically removed.\n",
+                       count, removed);
+               printf("Approximation after node accounting: %lu nodes.\n",
+                       approx_after);
+       }
        ret = cds_lfht_destroy(test_ht, NULL);
 
        if (ret)
index 1f3071019f4495a2570d2d2ba0d4f083ed29714e..1c1f03b51d904d3aab6c9e50c8e7aa8f47d47c2f 100644 (file)
@@ -165,8 +165,10 @@ int cds_lfht_destroy(struct cds_lfht *ht, pthread_attr_t **attr);
  * Call with rcu_read_lock held.
  */
 void cds_lfht_count_nodes(struct cds_lfht *ht,
+               unsigned long *approx_before,
                unsigned long *count,
-               unsigned long *removed);
+               unsigned long *removed,
+               unsigned long *approx_after);
 
 /*
  * cds_lfht_lookup - lookup a node by key.
This page took 0.029651 seconds and 4 git commands to generate.