rculfqueue: LGPL-ize
[urcu.git] / urcu / rculfstack.h
index f43c9d8c1e679c344bdb289b445fdd99ed0c466d..8cf7d13b35cc09ffc79f6646dd9c0d2c75b3e9b5 100644 (file)
@@ -1,3 +1,6 @@
+#ifndef _URCU_RCULFSTACK_H
+#define _URCU_RCULFSTACK_H
+
 /*
  * rculfstack.h
  *
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #if (!defined(_GNU_SOURCE) && !defined(_LGPL_SOURCE))
 #error "Dynamic loader LGPL wrappers not implemented yet"
 #endif
@@ -43,10 +50,11 @@ void rcu_lfs_init(struct rcu_lfs_stack *s)
 
 void rcu_lfs_push(struct rcu_lfs_stack *s, struct rcu_lfs_node *node)
 {
-       rcu_read_lock();
        for (;;) {
-               struct rcu_lfs_node *head = rcu_dereference(s->head);
+               struct rcu_lfs_node *head;
 
+               rcu_read_lock();
+               head = rcu_dereference(s->head);
                node->next = head;
                /*
                 * uatomic_cmpxchg() implicit memory barrier orders earlier
@@ -57,18 +65,25 @@ void rcu_lfs_push(struct rcu_lfs_stack *s, struct rcu_lfs_node *node)
                        return;
                } else {
                        /* Failure to prepend. Retry. */
+                       rcu_read_unlock();
                        continue;
                }
        }
 }
 
+/*
+ * The caller must wait for a grace period to pass before freeing the returned
+ * node or modifying the rcu_lfs_node structure.
+ * Returns NULL if stack is empty.
+ */
 struct rcu_lfs_node *
 rcu_lfs_pop(struct rcu_lfs_stack *s)
 {
-       rcu_read_lock();
        for (;;) {
-               struct rcu_lfs_node *head = rcu_dereference(s->head);
+               struct rcu_lfs_node *head;
 
+               rcu_read_lock();
+               head = rcu_dereference(s->head);
                if (head) {
                        struct rcu_lfs_node *next = rcu_dereference(head->next);
 
@@ -77,6 +92,7 @@ rcu_lfs_pop(struct rcu_lfs_stack *s)
                                return head;
                        } else {
                                /* Concurrent modification. Retry. */
+                               rcu_read_unlock();
                                continue;
                        }
                } else {
@@ -86,3 +102,9 @@ rcu_lfs_pop(struct rcu_lfs_stack *s)
                }
        }
 }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _URCU_RCULFSTACK_H */
This page took 0.025581 seconds and 4 git commands to generate.