From: Mathieu Desnoyers Date: Mon, 13 Aug 2012 12:26:55 +0000 (-0400) Subject: rcuja: new and destroy X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=be9a7474cac017c7d0bed96efdb86e50ed0f6376;p=userspace-rcu.git rcuja: new and destroy Signed-off-by: Mathieu Desnoyers --- diff --git a/rcuja/rcuja-internal.h b/rcuja/rcuja-internal.h index b1d7baa..551cad6 100644 --- a/rcuja/rcuja-internal.h +++ b/rcuja/rcuja-internal.h @@ -58,13 +58,14 @@ struct cds_ja { __attribute__((visibility("protected"))) struct cds_ja_shadow_node *rcuja_shadow_lookup_lock(struct cds_lfht *ht, struct cds_ja_node *node); + __attribute__((visibility("protected"))) void rcuja_shadow_unlock(struct cds_ja_shadow_node *shadow_node); + __attribute__((visibility("protected"))) int rcuja_shadow_set(struct cds_lfht *ht, struct cds_ja_node *new_node, struct cds_ja_shadow_node *inherit_from); -__attribute__((visibility("protected"))) /* rcuja_shadow_clear flags */ enum { @@ -72,12 +73,19 @@ enum { RCUJA_SHADOW_CLEAR_FREE_LOCK = (1U << 1), }; +__attribute__((visibility("protected"))) int rcuja_shadow_clear(struct cds_lfht *ht, struct cds_ja_node *node, unsigned int flags); + +__attribute__((visibility("protected"))) +void rcuja_shadow_prune(struct cds_lfht *ht, + unsigned int flags); + __attribute__((visibility("protected"))) struct cds_lfht *rcuja_create_ht(const struct rcu_flavor_struct *flavor); + __attribute__((visibility("protected"))) -void rcuja_delete_ht(struct cds_lfht *ht); +int rcuja_delete_ht(struct cds_lfht *ht); #endif /* _URCU_RCUJA_INTERNAL_H */ diff --git a/rcuja/rcuja-shadow-nodes.c b/rcuja/rcuja-shadow-nodes.c index cfc7073..e042cf2 100644 --- a/rcuja/rcuja-shadow-nodes.c +++ b/rcuja/rcuja-shadow-nodes.c @@ -329,6 +329,38 @@ rcu_unlock: return ret; } +/* + * Delete all shadow nodes and nodes from hash table, along with their + * associated lock. + */ +__attribute__((visibility("protected"))) +void rcuja_shadow_prune(struct cds_lfht *ht, + unsigned int flags) +{ + const struct rcu_flavor_struct *flavor; + struct cds_ja_shadow_node *shadow_node; + struct cds_lfht_iter iter; + int ret, lockret; + + flavor = cds_lfht_rcu_flavor(ht); + flavor->read_lock(); + cds_lfht_for_each_entry(ht, &iter, shadow_node, ht_node) { + lockret = pthread_mutex_lock(shadow_node->lock); + assert(!lockret); + + ret = cds_lfht_del(ht, &shadow_node->ht_node); + if (!ret) { + assert((flags & RCUJA_SHADOW_CLEAR_FREE_NODE) + && (flags & RCUJA_SHADOW_CLEAR_FREE_LOCK)); + flavor->update_call_rcu(&shadow_node->head, + free_shadow_node_and_node_and_lock); + } + lockret = pthread_mutex_unlock(shadow_node->lock); + assert(!lockret); + } + flavor->read_unlock(); +} + __attribute__((visibility("protected"))) struct cds_lfht *rcuja_create_ht(const struct rcu_flavor_struct *flavor) { @@ -338,12 +370,9 @@ struct cds_lfht *rcuja_create_ht(const struct rcu_flavor_struct *flavor) } __attribute__((visibility("protected"))) -void rcuja_delete_ht(struct cds_lfht *ht) +int rcuja_delete_ht(struct cds_lfht *ht) { - int ret; - - ret = cds_lfht_destroy(ht, NULL); - assert(!ret); + return cds_lfht_destroy(ht, NULL); } __attribute__((constructor)) diff --git a/rcuja/rcuja.c b/rcuja/rcuja.c index 905375c..adb7b49 100644 --- a/rcuja/rcuja.c +++ b/rcuja/rcuja.c @@ -681,3 +681,33 @@ int ja_node_set_nth(struct cds_ja *ja, rcuja_shadow_unlock(shadow_node); return ret; } + +struct cds_ja *_cds_ja_new(const struct rcu_flavor_struct *flavor) +{ + struct cds_ja *ja; + + ja = calloc(sizeof(*ja), 1); + if (!ja) + goto ja_error; + /* ja->root is NULL */ + ja->ht = rcuja_create_ht(flavor); + if (!ja->ht) + goto ht_error; + return ja; + +ht_error: + free(ja); +ja_error: + return NULL; +} + +/* + * There should be no more concurrent add to the judy array while it is + * being destroyed (ensured by the caller). + */ +int cds_ja_destroy(struct cds_ja *ja) +{ + rcuja_shadow_prune(ja->ht, + RCUJA_SHADOW_CLEAR_FREE_NODE | RCUJA_SHADOW_CLEAR_FREE_LOCK); + return rcuja_delete_ht(ja->ht); +}