Commit | Line | Data |
---|---|---|
fdee2e6d MD |
1 | #ifndef _URCU_BP_H |
2 | #define _URCU_BP_H | |
3 | ||
4 | /* | |
5 | * urcu-bp.h | |
6 | * | |
7 | * Userspace RCU header, "bulletproof" version. | |
8 | * | |
9 | * Slower RCU read-side adapted for tracing library. Does not require thread | |
10 | * registration nor unregistration. Also signal-safe. | |
11 | * | |
6982d6d7 | 12 | * Copyright (c) 2009 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> |
fdee2e6d MD |
13 | * Copyright (c) 2009 Paul E. McKenney, IBM Corporation. |
14 | * | |
15 | * LGPL-compatible code should include this header with : | |
16 | * | |
17 | * #define _LGPL_SOURCE | |
18 | * #include <urcu.h> | |
19 | * | |
20 | * This library is free software; you can redistribute it and/or | |
21 | * modify it under the terms of the GNU Lesser General Public | |
22 | * License as published by the Free Software Foundation; either | |
23 | * version 2.1 of the License, or (at your option) any later version. | |
24 | * | |
25 | * This library is distributed in the hope that it will be useful, | |
26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
28 | * Lesser General Public License for more details. | |
29 | * | |
30 | * You should have received a copy of the GNU Lesser General Public | |
31 | * License along with this library; if not, write to the Free Software | |
32 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
33 | * | |
34 | * IBM's contributions to this file may be relicensed under LGPLv2 or later. | |
35 | */ | |
36 | ||
37 | #include <stdlib.h> | |
38 | #include <pthread.h> | |
111bda8f | 39 | #include <stdbool.h> |
fdee2e6d | 40 | |
ee6fabe1 | 41 | #include <urcu/map/urcu-bp.h> |
5e77fc1f | 42 | |
fdee2e6d MD |
43 | /* |
44 | * Important ! | |
45 | * | |
46 | * Each thread containing read-side critical sections must be registered | |
47 | * with rcu_register_thread() before calling rcu_read_lock(). | |
48 | * rcu_unregister_thread() should be called before the thread exits. | |
49 | */ | |
50 | ||
5efd3cd2 | 51 | /* |
6cd23d47 | 52 | * See urcu/pointer.h and urcu/static/pointer.h for pointer |
5efd3cd2 MD |
53 | * publication headers. |
54 | */ | |
6cd23d47 | 55 | #include <urcu/pointer.h> |
111bda8f | 56 | #include <urcu/urcu-poll.h> |
5efd3cd2 | 57 | |
2ad3cfeb SM |
58 | #ifdef __cplusplus |
59 | extern "C" { | |
60 | #endif | |
61 | ||
fdee2e6d MD |
62 | #ifdef _LGPL_SOURCE |
63 | ||
af7c2dbe | 64 | #include <urcu/static/urcu-bp.h> |
fdee2e6d MD |
65 | |
66 | /* | |
67 | * Mappings for static use of the userspace RCU library. | |
68 | * Should only be used in LGPL-compatible code. | |
69 | */ | |
70 | ||
71 | /* | |
72 | * rcu_read_lock() | |
73 | * rcu_read_unlock() | |
74 | * | |
75 | * Mark the beginning and end of a read-side critical section. | |
76 | */ | |
4477a870 MD |
77 | #define urcu_bp_read_lock _urcu_bp_read_lock |
78 | #define urcu_bp_read_unlock _urcu_bp_read_unlock | |
79 | #define urcu_bp_read_ongoing _urcu_bp_read_ongoing | |
fdee2e6d | 80 | |
4477a870 MD |
81 | #define urcu_bp_dereference rcu_dereference |
82 | #define urcu_bp_cmpxchg_pointer rcu_cmpxchg_pointer | |
83 | #define urcu_bp_xchg_pointer rcu_xchg_pointer | |
84 | #define urcu_bp_set_pointer rcu_set_pointer | |
5efd3cd2 | 85 | |
fdee2e6d MD |
86 | #else /* !_LGPL_SOURCE */ |
87 | ||
88 | /* | |
89 | * library wrappers to be used by non-LGPL compatible source code. | |
6cd23d47 | 90 | * See LGPL-only urcu/static/pointer.h for documentation. |
fdee2e6d MD |
91 | */ |
92 | ||
4477a870 MD |
93 | extern void urcu_bp_read_lock(void); |
94 | extern void urcu_bp_read_unlock(void); | |
95 | extern int urcu_bp_read_ongoing(void); | |
5efd3cd2 | 96 | |
4477a870 MD |
97 | extern void *urcu_bp_dereference_sym(void *p); |
98 | #define urcu_bp_dereference(p) \ | |
1b85da85 | 99 | __extension__ \ |
5efd3cd2 | 100 | ({ \ |
bdffa73a | 101 | __typeof__(p) _________p1 = URCU_FORCE_CAST(__typeof__(p), \ |
4477a870 | 102 | urcu_bp_dereference_sym(URCU_FORCE_CAST(void *, p))); \ |
5efd3cd2 MD |
103 | (_________p1); \ |
104 | }) | |
105 | ||
4477a870 MD |
106 | extern void *urcu_bp_cmpxchg_pointer_sym(void **p, void *old, void *_new); |
107 | #define urcu_bp_cmpxchg_pointer(p, old, _new) \ | |
1b85da85 | 108 | __extension__ \ |
5efd3cd2 | 109 | ({ \ |
bdffa73a MD |
110 | __typeof__(*(p)) _________pold = (old); \ |
111 | __typeof__(*(p)) _________pnew = (_new); \ | |
112 | __typeof__(*(p)) _________p1 = URCU_FORCE_CAST(__typeof__(*(p)), \ | |
4477a870 | 113 | urcu_bp_cmpxchg_pointer_sym(URCU_FORCE_CAST(void **, p), \ |
5efd3cd2 MD |
114 | _________pold, \ |
115 | _________pnew)); \ | |
116 | (_________p1); \ | |
117 | }) | |
118 | ||
4477a870 MD |
119 | extern void *urcu_bp_xchg_pointer_sym(void **p, void *v); |
120 | #define urcu_bp_xchg_pointer(p, v) \ | |
1b85da85 | 121 | __extension__ \ |
5efd3cd2 | 122 | ({ \ |
bdffa73a MD |
123 | __typeof__(*(p)) _________pv = (v); \ |
124 | __typeof__(*(p)) _________p1 = URCU_FORCE_CAST(__typeof__(*(p)),\ | |
4477a870 | 125 | urcu_bp_xchg_pointer_sym(URCU_FORCE_CAST(void **, p), \ |
5efd3cd2 MD |
126 | _________pv)); \ |
127 | (_________p1); \ | |
128 | }) | |
129 | ||
4477a870 MD |
130 | extern void *urcu_bp_set_pointer_sym(void **p, void *v); |
131 | #define urcu_bp_set_pointer(p, v) \ | |
1b85da85 | 132 | __extension__ \ |
5efd3cd2 | 133 | ({ \ |
bdffa73a MD |
134 | __typeof__(*(p)) _________pv = (v); \ |
135 | __typeof__(*(p)) _________p1 = URCU_FORCE_CAST(__typeof__(*(p)), \ | |
4477a870 | 136 | urcu_bp_set_pointer_sym(URCU_FORCE_CAST(void **, p), \ |
5efd3cd2 MD |
137 | _________pv)); \ |
138 | (_________p1); \ | |
139 | }) | |
fdee2e6d MD |
140 | |
141 | #endif /* !_LGPL_SOURCE */ | |
142 | ||
4477a870 | 143 | extern void urcu_bp_synchronize_rcu(void); |
fdee2e6d | 144 | |
111bda8f MD |
145 | /* |
146 | * RCU grace period polling API. | |
147 | */ | |
148 | extern struct urcu_gp_poll_state urcu_bp_start_poll_synchronize_rcu(void); | |
149 | extern bool urcu_bp_poll_state_synchronize_rcu(struct urcu_gp_poll_state state); | |
150 | ||
4cf1675f | 151 | /* |
4477a870 | 152 | * urcu_bp_before_fork, urcu_bp_after_fork_parent and urcu_bp_after_fork_child |
4cf1675f MD |
153 | * should be called around fork() system calls when the child process is not |
154 | * expected to immediately perform an exec(). For pthread users, see | |
155 | * pthread_atfork(3). | |
156 | */ | |
4477a870 MD |
157 | extern void urcu_bp_before_fork(void); |
158 | extern void urcu_bp_after_fork_parent(void); | |
159 | extern void urcu_bp_after_fork_child(void); | |
4cf1675f | 160 | |
fdee2e6d | 161 | /* |
5b46e39d MD |
162 | * In the bulletproof version, thread registration is performed lazily, |
163 | * but it can be forced by issuing an explicit urcu_bp_register_thread(). | |
fdee2e6d | 164 | */ |
5b46e39d | 165 | extern void urcu_bp_register_thread(void); |
fdee2e6d | 166 | |
5b46e39d MD |
167 | /* |
168 | * In the bulletproof version, the following functions are no-ops. | |
169 | */ | |
4477a870 | 170 | static inline void urcu_bp_unregister_thread(void) |
fdee2e6d MD |
171 | { |
172 | } | |
173 | ||
4477a870 | 174 | static inline void urcu_bp_init(void) |
fdee2e6d MD |
175 | { |
176 | } | |
177 | ||
51b03c6f MD |
178 | /* |
179 | * Q.S. reporting are no-ops for these URCU flavors. | |
180 | */ | |
4477a870 | 181 | static inline void urcu_bp_quiescent_state(void) |
51b03c6f MD |
182 | { |
183 | } | |
184 | ||
4477a870 | 185 | static inline void urcu_bp_thread_offline(void) |
51b03c6f MD |
186 | { |
187 | } | |
188 | ||
4477a870 | 189 | static inline void urcu_bp_thread_online(void) |
51b03c6f MD |
190 | { |
191 | } | |
192 | ||
67ecffc0 | 193 | #ifdef __cplusplus |
36bc70a8 MD |
194 | } |
195 | #endif | |
196 | ||
6cd23d47 MD |
197 | #include <urcu/call-rcu.h> |
198 | #include <urcu/defer.h> | |
199 | #include <urcu/flavor.h> | |
5e77fc1f | 200 | |
4477a870 MD |
201 | #ifndef URCU_API_MAP |
202 | #include <urcu/map/clear.h> | |
203 | #endif | |
204 | ||
fdee2e6d | 205 | #endif /* _URCU_BP_H */ |