X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=rculfhash.c;h=cd25d336aea3ef781456c046699ef86e2de81b92;hb=d933dd0e116eceb59b1df0f223e3962a1e51bfb3;hp=1487980c832c115154937cda4b185024636f9e44;hpb=b198f0fda77c816d80f63cfa2e71a7e0b4496736;p=urcu.git diff --git a/rculfhash.c b/rculfhash.c index 1487980..cd25d33 100644 --- a/rculfhash.c +++ b/rculfhash.c @@ -246,7 +246,7 @@ struct cds_lfht { void (*cds_lfht_rcu_register_thread)(void); void (*cds_lfht_rcu_unregister_thread)(void); pthread_attr_t *resize_attr; /* Resize threads attributes */ - unsigned long count; /* global approximate item count */ + long count; /* global approximate item count */ struct ht_items_count *percpu_count; /* per-cpu item count */ }; @@ -556,7 +556,7 @@ void ht_count_add(struct cds_lfht *ht, unsigned long size) return; percpu_count = uatomic_add_return(&ht->percpu_count[cpu].add, 1); if (unlikely(!(percpu_count & ((1UL << COUNT_COMMIT_ORDER) - 1)))) { - unsigned long count; + long count; dbg_printf("add percpu %lu\n", percpu_count); count = uatomic_add_return(&ht->count, @@ -565,7 +565,7 @@ void ht_count_add(struct cds_lfht *ht, unsigned long size) if (!(count & (count - 1))) { if ((count >> CHAIN_LEN_RESIZE_THRESHOLD) < size) return; - dbg_printf("add set global %lu\n", count); + dbg_printf("add set global %ld\n", count); cds_lfht_resize_lazy_count(ht, size, count >> (CHAIN_LEN_TARGET - 1)); } @@ -583,9 +583,9 @@ void ht_count_del(struct cds_lfht *ht, unsigned long size) cpu = ht_get_cpu(); if (unlikely(cpu < 0)) return; - percpu_count = uatomic_add_return(&ht->percpu_count[cpu].del, -1); + percpu_count = uatomic_add_return(&ht->percpu_count[cpu].del, 1); if (unlikely(!(percpu_count & ((1UL << COUNT_COMMIT_ORDER) - 1)))) { - unsigned long count; + long count; dbg_printf("del percpu %lu\n", percpu_count); count = uatomic_add_return(&ht->count, @@ -594,7 +594,13 @@ void ht_count_del(struct cds_lfht *ht, unsigned long size) if (!(count & (count - 1))) { if ((count >> CHAIN_LEN_RESIZE_THRESHOLD) >= size) return; - dbg_printf("del set global %lu\n", count); + dbg_printf("del set global %ld\n", count); + /* + * Don't shrink table if the number of nodes is below a + * certain threshold. + */ + if (count < (1UL << COUNT_COMMIT_ORDER) * (nr_cpus_mask + 1)) + return; cds_lfht_resize_lazy_count(ht, size, count >> (CHAIN_LEN_TARGET - 1)); } @@ -1446,13 +1452,25 @@ int cds_lfht_destroy(struct cds_lfht *ht, pthread_attr_t **attr) } void cds_lfht_count_nodes(struct cds_lfht *ht, + long *approx_before, unsigned long *count, - unsigned long *removed) + unsigned long *removed, + long *approx_after) { struct cds_lfht_node *node, *next; struct _cds_lfht_node *lookup; unsigned long nr_dummy = 0; + *approx_before = 0; + 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 +1480,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 +1491,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 = 0; + 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 */