From: Lai Jiangshan Date: Mon, 17 Oct 2011 13:32:00 +0000 (-0400) Subject: rculfhash: make struct rcu_level size power of 2 X-Git-Tag: v0.7.0~43^2~93 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=0d14ceb26e0ff3e1d6f86cf3ec9674ee3b16e96f;p=urcu.git rculfhash: make struct rcu_level size power of 2 By adding a small slowpath overhead (added synchronize_rcu call in the last iteration of the resize), we can reduce the amount of wasted memory for memory allocators that allocate power of two memory areas. This is achieved by removing the call_rcu head from struct rcu_level. [ Edit by Mathieu Desnoyers: - add comment about need to manually update the allocation size of fields are added to struct rcu_level. - create a more explanatory title and changelog. ] Signed-off-by: Lai Jiangshan Signed-off-by: Mathieu Desnoyers --- diff --git a/rculfhash.c b/rculfhash.c index fe8beed..2e338f1 100644 --- a/rculfhash.c +++ b/rculfhash.c @@ -209,7 +209,7 @@ struct ht_items_count { } __attribute__((aligned(CAA_CACHE_LINE_SIZE))); struct rcu_level { - struct rcu_head head; + /* Note: manually update allocation length when adding a field */ struct _cds_lfht_node nodes[0]; }; @@ -716,14 +716,6 @@ unsigned long _uatomic_max(unsigned long *ptr, unsigned long v) return v; } -static -void cds_lfht_free_level(struct rcu_head *head) -{ - struct rcu_level *l = - caa_container_of(head, struct rcu_level, head); - poison_free(l); -} - /* * Remove all logically deleted nodes from a bucket up to a certain node key. */ @@ -1135,8 +1127,7 @@ void init_table(struct cds_lfht *ht, if (CMM_LOAD_SHARED(ht->t.resize_target) < (!i ? 1 : (1UL << i))) break; - ht->t.tbl[i] = calloc(1, sizeof(struct rcu_level) - + (len * sizeof(struct _cds_lfht_node))); + ht->t.tbl[i] = calloc(1, len * sizeof(struct _cds_lfht_node)); assert(ht->t.tbl[i]); /* @@ -1222,6 +1213,7 @@ void fini_table(struct cds_lfht *ht, unsigned long first_order, unsigned long len_order) { long i, end_order; + void *free_by_rcu = NULL; dbg_printf("fini table: first_order %lu end_order %lu\n", first_order, first_order + len_order); @@ -1247,6 +1239,8 @@ void fini_table(struct cds_lfht *ht, * return a logically removed node as insert position. */ ht->cds_lfht_synchronize_rcu(); + if (free_by_rcu) + free(free_by_rcu); /* * Set "removed" flag in dummy nodes about to be removed. @@ -1256,12 +1250,17 @@ void fini_table(struct cds_lfht *ht, */ remove_table(ht, i, len); - ht->cds_lfht_call_rcu(&ht->t.tbl[i]->head, cds_lfht_free_level); + free_by_rcu = ht->t.tbl[i]; dbg_printf("fini new size: %lu\n", 1UL << i); if (CMM_LOAD_SHARED(ht->in_progress_destroy)) break; } + + if (free_by_rcu) { + ht->cds_lfht_synchronize_rcu(); + free(free_by_rcu); + } } struct cds_lfht *_cds_lfht_new(cds_lfht_hash_fct hash_fct,