X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=rculfhash.c;h=074a6f4ea8c4c40f7b2f7374d3ecdc8387e34bff;hb=860d07e812c3001e9d6ce261c8b861dabd3203b3;hp=42501a1f030c6ee29fb0c40e5fdc02394da06992;hpb=b7d619b0a4d1613664285e3986b930a05c131c70;p=urcu.git diff --git a/rculfhash.c b/rculfhash.c index 42501a1..074a6f4 100644 --- a/rculfhash.c +++ b/rculfhash.c @@ -180,7 +180,8 @@ /* * Minimum number of dummy nodes to touch per thread to parallelize grow/shrink. */ -#define MIN_PARTITION_PER_THREAD 4096 +#define MIN_PARTITION_PER_THREAD_ORDER 12 +#define MIN_PARTITION_PER_THREAD (1UL << MIN_PARTITION_PER_THREAD_ORDER) #ifndef min #define min(a, b) ((a) < (b) ? (a) : (b)) @@ -203,7 +204,7 @@ #define END_VALUE NULL struct ht_items_count { - unsigned long add, remove; + unsigned long add, del; } __attribute__((aligned(CAA_CACHE_LINE_SIZE))); struct rcu_level { @@ -564,7 +565,7 @@ void ht_count_add(struct cds_lfht *ht, unsigned long size) } static -void ht_count_remove(struct cds_lfht *ht, unsigned long size) +void ht_count_del(struct cds_lfht *ht, unsigned long size) { unsigned long percpu_count; int cpu; @@ -574,18 +575,18 @@ void ht_count_remove(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].remove, -1); + percpu_count = uatomic_add_return(&ht->percpu_count[cpu].del, -1); if (unlikely(!(percpu_count & ((1UL << COUNT_COMMIT_ORDER) - 1)))) { unsigned long count; - dbg_printf("remove percpu %lu\n", percpu_count); + dbg_printf("del percpu %lu\n", percpu_count); count = uatomic_add_return(&ht->count, -(1UL << COUNT_COMMIT_ORDER)); /* If power of 2 */ if (!(count & (count - 1))) { if ((count >> CHAIN_LEN_RESIZE_THRESHOLD) >= size) return; - dbg_printf("remove set global %lu\n", count); + dbg_printf("del set global %lu\n", count); cds_lfht_resize_lazy_count(ht, size, count >> (CHAIN_LEN_TARGET - 1)); } @@ -613,7 +614,7 @@ void ht_count_add(struct cds_lfht *ht, unsigned long size) } static -void ht_count_remove(struct cds_lfht *ht, unsigned long size) +void ht_count_del(struct cds_lfht *ht, unsigned long size) { } @@ -843,7 +844,7 @@ gc_end: } static -int _cds_lfht_remove(struct cds_lfht *ht, unsigned long size, +int _cds_lfht_del(struct cds_lfht *ht, unsigned long size, struct cds_lfht_node *node, int dummy_removal) { @@ -914,26 +915,33 @@ void partition_resize_helper(struct cds_lfht *ht, unsigned long i, { unsigned long partition_len; struct partition_resize_work *work; - int cpu, ret; + int thread, ret; + unsigned long nr_threads; pthread_t *thread_id; - /* Note: nr_cpus_mask + 1 is always power of 2 */ - partition_len = len >> get_count_order_ulong(nr_cpus_mask + 1); - work = calloc(nr_cpus_mask + 1, sizeof(*work)); - thread_id = calloc(nr_cpus_mask + 1, sizeof(*thread_id)); + /* + * Note: nr_cpus_mask + 1 is always power of 2. + * We spawn just the number of threads we need to satisfy the minimum + * partition size, up to the number of CPUs in the system. + */ + nr_threads = min(nr_cpus_mask + 1, + len >> MIN_PARTITION_PER_THREAD_ORDER); + partition_len = len >> get_count_order_ulong(nr_threads); + work = calloc(nr_threads, sizeof(*work)); + thread_id = calloc(nr_threads, sizeof(*thread_id)); assert(work); - for (cpu = 0; cpu < nr_cpus_mask + 1; cpu++) { - work[cpu].ht = ht; - work[cpu].i = i; - work[cpu].len = partition_len; - work[cpu].start = cpu * partition_len; - work[cpu].fct = fct; - ret = pthread_create(&thread_id[cpu], ht->resize_attr, - partition_resize_thread, &work[cpu]); + for (thread = 0; thread < nr_threads; thread++) { + work[thread].ht = ht; + work[thread].i = i; + work[thread].len = partition_len; + work[thread].start = thread * partition_len; + work[thread].fct = fct; + ret = pthread_create(&thread_id[thread], ht->resize_attr, + partition_resize_thread, &work[thread]); assert(!ret); } - for (cpu = 0; cpu < nr_cpus_mask + 1; cpu++) { - ret = pthread_join(thread_id[cpu], NULL); + for (thread = 0; thread < nr_threads; thread++) { + ret = pthread_join(thread_id[thread], NULL); assert(!ret); } free(work); @@ -979,7 +987,7 @@ void init_table_populate(struct cds_lfht *ht, unsigned long i, unsigned long len) { assert(nr_cpus_mask != -1); - if (nr_cpus_mask < 0 || len < (nr_cpus_mask + 1) * MIN_PARTITION_PER_THREAD) { + if (nr_cpus_mask < 0 || len < 2 * MIN_PARTITION_PER_THREAD) { ht->cds_lfht_rcu_thread_online(); init_table_populate_partition(ht, i, 0, len); ht->cds_lfht_rcu_thread_offline(); @@ -1069,7 +1077,7 @@ void remove_table_partition(struct cds_lfht *ht, unsigned long i, i, j, !i ? 0 : (1UL << (i - 1)) + j); fini_node->p.reverse_hash = bit_reverse_ulong(!i ? 0 : (1UL << (i - 1)) + j); - (void) _cds_lfht_remove(ht, !i ? 0 : (1UL << (i - 1)), + (void) _cds_lfht_del(ht, !i ? 0 : (1UL << (i - 1)), fini_node, 1); if (CMM_LOAD_SHARED(ht->in_progress_destroy)) break; @@ -1082,7 +1090,7 @@ void remove_table(struct cds_lfht *ht, unsigned long i, unsigned long len) { assert(nr_cpus_mask != -1); - if (nr_cpus_mask < 0 || len < (nr_cpus_mask + 1) * MIN_PARTITION_PER_THREAD) { + if (nr_cpus_mask < 0 || len < 2 * MIN_PARTITION_PER_THREAD) { ht->cds_lfht_rcu_thread_online(); remove_table_partition(ht, i, 0, len); ht->cds_lfht_rcu_thread_offline(); @@ -1291,15 +1299,15 @@ struct cds_lfht_node *cds_lfht_add_unique(struct cds_lfht *ht, return ret; } -int cds_lfht_remove(struct cds_lfht *ht, struct cds_lfht_node *node) +int cds_lfht_del(struct cds_lfht *ht, struct cds_lfht_node *node) { unsigned long size; int ret; size = rcu_dereference(ht->t.size); - ret = _cds_lfht_remove(ht, size, node, 0); + ret = _cds_lfht_del(ht, size, node, 0); if (!ret) - ht_count_remove(ht, size); + ht_count_del(ht, size); return ret; }