urcu static coding style fix (whitespace)
[urcu.git] / urcu / rculfstack.h
... / ...
CommitLineData
1#ifndef _URCU_RCULFSTACK_H
2#define _URCU_RCULFSTACK_H
3
4/*
5 * rculfstack.h
6 *
7 * Userspace RCU library - Lock-Free RCU Stack
8 *
9 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#if (!defined(_GNU_SOURCE) && !defined(_LGPL_SOURCE))
27#error "Dynamic loader LGPL wrappers not implemented yet"
28#endif
29
30struct rcu_lfs_node {
31 struct rcu_lfs_node *next;
32};
33
34struct rcu_lfs_stack {
35 struct rcu_lfs_node *head;
36};
37
38void rcu_lfs_node_init(struct rcu_lfs_node *node)
39{
40}
41
42void rcu_lfs_init(struct rcu_lfs_stack *s)
43{
44 s->head = NULL;
45}
46
47void rcu_lfs_push(struct rcu_lfs_stack *s, struct rcu_lfs_node *node)
48{
49 for (;;) {
50 struct rcu_lfs_node *head;
51
52 rcu_read_lock();
53 head = rcu_dereference(s->head);
54 node->next = head;
55 /*
56 * uatomic_cmpxchg() implicit memory barrier orders earlier
57 * stores to node before publication.
58 */
59 if (uatomic_cmpxchg(&s->head, head, node) == head) {
60 rcu_read_unlock();
61 return;
62 } else {
63 /* Failure to prepend. Retry. */
64 rcu_read_unlock();
65 continue;
66 }
67 }
68}
69
70/*
71 * The caller must wait for a grace period to pass before freeing the returned
72 * node.
73 * Returns NULL if stack is empty.
74 */
75struct rcu_lfs_node *
76rcu_lfs_pop(struct rcu_lfs_stack *s)
77{
78 for (;;) {
79 struct rcu_lfs_node *head;
80
81 rcu_read_lock();
82 head = rcu_dereference(s->head);
83 if (head) {
84 struct rcu_lfs_node *next = rcu_dereference(head->next);
85
86 if (uatomic_cmpxchg(&s->head, head, next) == head) {
87 rcu_read_unlock();
88 return head;
89 } else {
90 /* Concurrent modification. Retry. */
91 rcu_read_unlock();
92 continue;
93 }
94 } else {
95 /* Empty stack */
96 rcu_read_unlock();
97 return NULL;
98 }
99 }
100}
101
102#endif /* _URCU_RCULFSTACK_H */
This page took 0.021663 seconds and 4 git commands to generate.