urcu lfstack: pop needs rcu read lock
authorMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Wed, 25 Aug 2010 15:16:34 +0000 (11:16 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Wed, 25 Aug 2010 15:16:34 +0000 (11:16 -0400)
The pop side needs to hold the RCU read lock to deal with ABA problem.
The push side does not need to hold the RCU read lock because even if the next
item is changed to the same value initially read, the stack will still be
consistent.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
urcu/rculfstack-static.h

index 49e5ef4adf905530d82577544d35ae6e1602f895..3ce24c55d2ddcf385f9e90006a016b305b557766 100644 (file)
@@ -68,22 +68,28 @@ void _rcu_lfs_push(struct rcu_lfs_stack *s, struct rcu_lfs_node *node)
 struct rcu_lfs_node *
 _rcu_lfs_pop(struct rcu_lfs_stack *s)
 {
-       struct rcu_lfs_node *head = NULL;
-
        for (;;) {
-               struct rcu_lfs_node *old_head = head;
-               struct rcu_lfs_node *next;
+               struct rcu_lfs_node *head;
 
-               if (head)
-                       next = head->next;
-               else
-                       next = NULL;
+               rcu_read_lock();
+               head = rcu_dereference(s->head);
+               if (head) {
+                       struct rcu_lfs_node *next = rcu_dereference(head->next);
 
-               head = uatomic_cmpxchg(&s->head, old_head, next);
-               if (old_head == head)
-                       break;
+                       if (uatomic_cmpxchg(&s->head, head, next) == head) {
+                               rcu_read_unlock();
+                               return head;
+                       } else {
+                               /* Concurrent modification. Retry. */
+                               rcu_read_unlock();
+                               continue;
+                       }
+               } else {
+                       /* Empty stack */
+                       rcu_read_unlock();
+                       return NULL;
+               }
        }
-       return head;
 }
 
 #ifdef __cplusplus
This page took 0.025583 seconds and 4 git commands to generate.