Commit | Line | Data |
---|---|---|
1c196845 MJ |
1 | // SPDX-FileCopyrightText: 2009 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> |
2 | // SPDX-FileCopyrightText: 2009 Paul E. McKenney, IBM Corporation. | |
3 | // | |
4 | // SPDX-License-Identifier: LGPL-2.1-or-later | |
5 | ||
10544ee8 | 6 | /* |
c0c0989a | 7 | * Userspace RCU header. Operations on pointers. |
10544ee8 MD |
8 | */ |
9 | ||
c0c0989a MJ |
10 | #ifndef _LTTNG_UST_URCU_POINTER_H |
11 | #define _LTTNG_UST_URCU_POINTER_H | |
12 | ||
10544ee8 MD |
13 | #include <urcu/compiler.h> |
14 | #include <urcu/arch.h> | |
15 | #include <urcu/uatomic.h> | |
16 | ||
17 | #ifdef __cplusplus | |
18 | extern "C" { | |
19 | #endif | |
20 | ||
21 | #if defined(_LGPL_SOURCE) || defined(LTTNG_UST_URCU_INLINE_SMALL_FUNCTIONS) | |
22 | ||
23 | #include <lttng/urcu/static/pointer.h> | |
24 | ||
25 | /* | |
26 | * lttng_ust_rcu_dereference(ptr) | |
27 | * | |
28 | * Fetch a RCU-protected pointer. Typically used to copy the variable ptr to a | |
29 | * local variable. | |
30 | */ | |
31 | #define lttng_ust_rcu_dereference _lttng_ust_rcu_dereference | |
32 | ||
33 | /* | |
34 | * type *lttng_ust_rcu_cmpxchg_pointer(type **ptr, type *new, type *old) | |
35 | * type *lttng_ust_rcu_xchg_pointer(type **ptr, type *new) | |
36 | * void lttng_ust_rcu_set_pointer(type **ptr, type *new) | |
37 | * | |
38 | * RCU pointer updates. | |
39 | * @ptr: address of the pointer to modify | |
40 | * @new: new pointer value | |
41 | * @old: old pointer value (expected) | |
42 | * | |
43 | * return: old pointer value | |
44 | */ | |
45 | #define lttng_ust_rcu_cmpxchg_pointer _lttng_ust_rcu_cmpxchg_pointer | |
46 | #define lttng_ust_rcu_xchg_pointer _lttng_ust_rcu_xchg_pointer | |
47 | #define lttng_ust_rcu_set_pointer _lttng_ust_rcu_set_pointer | |
48 | ||
49 | #else /* !(defined(_LGPL_SOURCE) || defined(LTTNG_UST_URCU_INLINE_SMALL_FUNCTIONS)) */ | |
50 | ||
51 | extern void *lttng_ust_rcu_dereference_sym(void *p); | |
52 | #define lttng_ust_rcu_dereference(p) \ | |
53 | __extension__ \ | |
54 | ({ \ | |
55 | __typeof__(p) _________p1 = URCU_FORCE_CAST(__typeof__(p), \ | |
56 | lttng_ust_rcu_dereference_sym(URCU_FORCE_CAST(void *, p))); \ | |
57 | (_________p1); \ | |
58 | }) | |
59 | ||
60 | extern void *lttng_ust_rcu_cmpxchg_pointer_sym(void **p, void *old, void *_new); | |
61 | #define lttng_ust_rcu_cmpxchg_pointer(p, old, _new) \ | |
62 | __extension__ \ | |
63 | ({ \ | |
64 | __typeof__(*(p)) _________pold = (old); \ | |
65 | __typeof__(*(p)) _________pnew = (_new); \ | |
66 | __typeof__(*(p)) _________p1 = URCU_FORCE_CAST(__typeof__(*(p)), \ | |
67 | lttng_ust_rcu_cmpxchg_pointer_sym(URCU_FORCE_CAST(void **, p), \ | |
68 | _________pold, \ | |
69 | _________pnew)); \ | |
70 | (_________p1); \ | |
71 | }) | |
72 | ||
73 | extern void *lttng_ust_rcu_xchg_pointer_sym(void **p, void *v); | |
74 | #define lttng_ust_rcu_xchg_pointer(p, v) \ | |
75 | __extension__ \ | |
76 | ({ \ | |
77 | __typeof__(*(p)) _________pv = (v); \ | |
78 | __typeof__(*(p)) _________p1 = URCU_FORCE_CAST(__typeof__(*(p)), \ | |
79 | lttng_ust_rcu_xchg_pointer_sym(URCU_FORCE_CAST(void **, p), \ | |
80 | _________pv)); \ | |
81 | (_________p1); \ | |
82 | }) | |
83 | ||
84 | /* | |
85 | * Note: lttng_ust_rcu_set_pointer_sym returns @v because we don't want to break | |
86 | * the ABI. At the API level, lttng_ust_rcu_set_pointer() now returns void. Use of | |
87 | * the return value is therefore deprecated, and will cause a build | |
88 | * error. | |
89 | */ | |
90 | extern void *lttng_ust_rcu_set_pointer_sym(void **p, void *v); | |
91 | #define lttng_ust_rcu_set_pointer(p, v) \ | |
92 | do { \ | |
93 | __typeof__(*(p)) _________pv = (v); \ | |
94 | (void) lttng_ust_rcu_set_pointer_sym(URCU_FORCE_CAST(void **, p), \ | |
95 | _________pv); \ | |
96 | } while (0) | |
97 | ||
98 | #endif /* !(defined(_LGPL_SOURCE) || defined(LTTNG_UST_URCU_INLINE_SMALL_FUNCTIONS)) */ | |
99 | ||
100 | /* | |
101 | * void lttng_ust_rcu_assign_pointer(type *ptr, type *new) | |
102 | * | |
103 | * Same as lttng_ust_rcu_set_pointer, but takes the pointer to assign to rather than its | |
104 | * address as first parameter. Provided for compatibility with the Linux kernel | |
105 | * RCU semantic. | |
106 | */ | |
107 | #define lttng_ust_rcu_assign_pointer(p, v) lttng_ust_rcu_set_pointer((&p), (v)) | |
108 | ||
109 | #ifdef __cplusplus | |
110 | } | |
111 | #endif | |
112 | ||
113 | #endif /* _LTTNG_UST_URCU_POINTER_H */ |