X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=rcuja%2Frcuja-shadow-nodes.c;h=2b369add76b7df205789f0aa0687639f32ae18a8;hb=41975c1208c75a5c428e841121637ed49fc00040;hp=cfc3aacebe311d5eccca6bc950957e25a57aa64a;hpb=5eb692c04e2089c97642bd1937343d90be04d691;p=userspace-rcu.git diff --git a/rcuja/rcuja-shadow-nodes.c b/rcuja/rcuja-shadow-nodes.c index cfc3aac..2b369ad 100644 --- a/rcuja/rcuja-shadow-nodes.c +++ b/rcuja/rcuja-shadow-nodes.c @@ -168,19 +168,19 @@ unsigned long hash_pointer(const void *_key, unsigned long seed) static int match_pointer(struct cds_lfht_node *node, const void *key) { - struct rcu_ja_shadow_node *shadow = - caa_container_of(node, struct rcu_ja_shadow_node, ht_node); + struct cds_ja_shadow_node *shadow = + caa_container_of(node, struct cds_ja_shadow_node, ht_node); return (key == shadow->node); } __attribute__((visibility("protected"))) -struct rcu_ja_shadow_node *rcuja_shadow_lookup_lock(struct cds_lfht *ht, - struct rcu_ja_node *node) +struct cds_ja_shadow_node *rcuja_shadow_lookup_lock(struct cds_lfht *ht, + struct cds_ja_inode *node) { struct cds_lfht_iter iter; struct cds_lfht_node *lookup_node; - struct rcu_ja_shadow_node *shadow_node; + struct cds_ja_shadow_node *shadow_node; const struct rcu_flavor_struct *flavor; int ret; @@ -195,11 +195,11 @@ struct rcu_ja_shadow_node *rcuja_shadow_lookup_lock(struct cds_lfht *ht, goto rcu_unlock; } shadow_node = caa_container_of(lookup_node, - struct rcu_ja_shadow_node, ht_node); - ret = pthread_mutex_lock(&shadow_node->lock); + struct cds_ja_shadow_node, ht_node); + ret = pthread_mutex_lock(shadow_node->lock); assert(!ret); if (cds_lfht_is_node_deleted(lookup_node)) { - ret = pthread_mutex_unlock(&shadow_node->lock); + ret = pthread_mutex_unlock(shadow_node->lock); assert(!ret); shadow_node = NULL; } @@ -209,19 +209,20 @@ rcu_unlock: } __attribute__((visibility("protected"))) -void rcuja_shadow_unlock(struct rcu_ja_shadow_node *shadow_node) +void rcuja_shadow_unlock(struct cds_ja_shadow_node *shadow_node) { int ret; - ret = pthread_mutex_unlock(&shadow_node->lock); + ret = pthread_mutex_unlock(shadow_node->lock); assert(!ret); } __attribute__((visibility("protected"))) int rcuja_shadow_set(struct cds_lfht *ht, - struct rcu_ja_node *node) + struct cds_ja_inode *new_node, + struct cds_ja_shadow_node *inherit_from) { - struct rcu_ja_shadow_node *shadow_node; + struct cds_ja_shadow_node *shadow_node; struct cds_lfht_node *ret_node; const struct rcu_flavor_struct *flavor; @@ -229,15 +230,27 @@ int rcuja_shadow_set(struct cds_lfht *ht, if (!shadow_node) return -ENOMEM; - shadow_node->node = node; - pthread_mutex_init(&shadow_node->lock, NULL); + shadow_node->node = new_node; + /* + * Lock can be inherited from previous node at this position. + */ + if (inherit_from) { + shadow_node->lock = inherit_from->lock; + } else { + shadow_node->lock = calloc(sizeof(*shadow_node->lock), 1); + if (!shadow_node->lock) { + free(shadow_node); + return -ENOMEM; + } + pthread_mutex_init(shadow_node->lock, NULL); + } flavor = cds_lfht_rcu_flavor(ht); flavor->read_lock(); ret_node = cds_lfht_add_unique(ht, - hash_pointer(node, hash_seed), + hash_pointer(new_node, hash_seed), match_pointer, - node, + new_node, &shadow_node->ht_node); flavor->read_unlock(); @@ -251,19 +264,30 @@ int rcuja_shadow_set(struct cds_lfht *ht, static void free_shadow_node_and_node(struct rcu_head *head) { - struct rcu_ja_shadow_node *shadow_node = - caa_container_of(head, struct rcu_ja_shadow_node, head); + struct cds_ja_shadow_node *shadow_node = + caa_container_of(head, struct cds_ja_shadow_node, head); free(shadow_node->node); free(shadow_node); } +static +void free_shadow_node_and_node_and_lock(struct rcu_head *head) +{ + struct cds_ja_shadow_node *shadow_node = + caa_container_of(head, struct cds_ja_shadow_node, head); + free(shadow_node->node); + free(shadow_node->lock); + free(shadow_node); +} + __attribute__((visibility("protected"))) -int rcuja_shadow_clear_and_free_node(struct cds_lfht *ht, - struct rcu_ja_node *node) +int rcuja_shadow_clear(struct cds_lfht *ht, + struct cds_ja_inode *node, + unsigned int flags) { struct cds_lfht_iter iter; struct cds_lfht_node *lookup_node; - struct rcu_ja_shadow_node *shadow_node; + struct cds_ja_shadow_node *shadow_node; const struct rcu_flavor_struct *flavor; int ret, lockret; @@ -277,8 +301,8 @@ int rcuja_shadow_clear_and_free_node(struct cds_lfht *ht, goto rcu_unlock; } shadow_node = caa_container_of(lookup_node, - struct rcu_ja_shadow_node, ht_node); - lockret = pthread_mutex_lock(&shadow_node->lock); + struct cds_ja_shadow_node, ht_node); + lockret = pthread_mutex_lock(shadow_node->lock); assert(!lockret); /* @@ -288,9 +312,16 @@ int rcuja_shadow_clear_and_free_node(struct cds_lfht *ht, */ ret = cds_lfht_del(ht, lookup_node); if (!ret) { - flavor->update_call_rcu(&shadow_node->head, free_shadow_node_and_node); + assert(flags & RCUJA_SHADOW_CLEAR_FREE_NODE); + if (flags & RCUJA_SHADOW_CLEAR_FREE_LOCK) { + flavor->update_call_rcu(&shadow_node->head, + free_shadow_node_and_node_and_lock); + } else { + flavor->update_call_rcu(&shadow_node->head, + free_shadow_node_and_node); + } } - lockret = pthread_mutex_unlock(&shadow_node->lock); + lockret = pthread_mutex_unlock(shadow_node->lock); assert(!lockret); rcu_unlock: flavor->read_unlock(); @@ -298,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) { @@ -307,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))