hlist: implement cds_hlist_first_entry_rcu
[userspace-rcu.git] / rcuja / rcuja-shadow-nodes.c
index 3a5de33669a9f53db204e6e473c9e928f48803c7..d6e4ff5db5212cbdda78eab45d6876a55bb862bd 100644 (file)
@@ -220,7 +220,7 @@ 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_shadow_node *rcuja_shadow_set(struct cds_lfht *ht,
                struct cds_ja_inode *new_node,
                struct cds_ja_shadow_node *inherit_from)
 {
@@ -230,7 +230,7 @@ int rcuja_shadow_set(struct cds_lfht *ht,
 
        shadow_node = calloc(sizeof(*shadow_node), 1);
        if (!shadow_node)
-               return -ENOMEM;
+               return NULL;
 
        shadow_node->node = new_node;
        /*
@@ -242,7 +242,7 @@ int rcuja_shadow_set(struct cds_lfht *ht,
                shadow_node->lock = calloc(sizeof(*shadow_node->lock), 1);
                if (!shadow_node->lock) {
                        free(shadow_node);
-                       return -ENOMEM;
+                       return NULL;
                }
                pthread_mutex_init(shadow_node->lock, NULL);
        }
@@ -258,9 +258,9 @@ int rcuja_shadow_set(struct cds_lfht *ht,
 
        if (ret_node != &shadow_node->ht_node) {
                free(shadow_node);
-               return -EEXIST;
+               return NULL;
        }
-       return 0;
+       return shadow_node;
 }
 
 static
@@ -294,6 +294,7 @@ 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);
+       assert(!shadow_node->is_root);
        free(shadow_node->node);
        free(shadow_node->lock);
        free(shadow_node);
@@ -337,7 +338,8 @@ int rcuja_shadow_clear(struct cds_lfht *ht,
         */
        ret = cds_lfht_del(ht, lookup_node);
        if (!ret) {
-               if (flags & RCUJA_SHADOW_CLEAR_FREE_NODE) {
+               if ((flags & RCUJA_SHADOW_CLEAR_FREE_NODE)
+                               && !shadow_node->is_root) {
                        if (flags & RCUJA_SHADOW_CLEAR_FREE_LOCK) {
                                flavor->update_call_rcu(&shadow_node->head,
                                        free_shadow_node_and_node_and_lock);
@@ -386,10 +388,24 @@ void rcuja_shadow_prune(struct cds_lfht *ht,
        
                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);
+                       if ((flags & RCUJA_SHADOW_CLEAR_FREE_NODE)
+                                       && !shadow_node->is_root) {
+                               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);
+                               }
+                       } else {
+                               if (flags & RCUJA_SHADOW_CLEAR_FREE_LOCK) {
+                                       flavor->update_call_rcu(&shadow_node->head,
+                                               free_shadow_node_and_lock);
+                               } else {
+                                       flavor->update_call_rcu(&shadow_node->head,
+                                               free_shadow_node);
+                               }
+                       }
                }
                lockret = pthread_mutex_unlock(shadow_node->lock);
                assert(!lockret);
This page took 0.035249 seconds and 4 git commands to generate.