This source file includes following definitions.
- pmix_atomic_mb
- pmix_atomic_wmb
- pmix_atomic_rmb
- pmix_atomic_fetch_min_32
- pmix_atomic_fetch_max_32
- pmix_atomic_fetch_min_64
- pmix_atomic_fetch_max_64
- pmix_atomic_min_fetch_32
- pmix_atomic_max_fetch_32
- pmix_atomic_min_fetch_64
- pmix_atomic_max_fetch_64
- pmix_atomic_lock_init
- pmix_atomic_trylock
- pmix_atomic_lock
- pmix_atomic_unlock
- pmix_atomic_compare_exchange_strong_128
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #if !defined(PMIX_ATOMIC_STDC_H)
23 #define PMIX_ATOMIC_STDC_H
24
25 #include <stdatomic.h>
26 #include <stdint.h>
27 #include "src/include/pmix_stdint.h"
28
29 #define PMIX_HAVE_ATOMIC_MEM_BARRIER 1
30
31 #define PMIX_HAVE_ATOMIC_COMPARE_EXCHANGE_32 1
32 #define PMIX_HAVE_ATOMIC_SWAP_32 1
33
34 #define PMIX_HAVE_ATOMIC_MATH_32 1
35 #define PMIX_HAVE_ATOMIC_ADD_32 1
36 #define PMIX_HAVE_ATOMIC_AND_32 1
37 #define PMIX_HAVE_ATOMIC_OR_32 1
38 #define PMIX_HAVE_ATOMIC_XOR_32 1
39 #define PMIX_HAVE_ATOMIC_SUB_32 1
40
41 #define PMIX_HAVE_ATOMIC_COMPARE_EXCHANGE_64 1
42 #define PMIX_HAVE_ATOMIC_SWAP_64 1
43
44 #define PMIX_HAVE_ATOMIC_MATH_64 1
45 #define PMIX_HAVE_ATOMIC_ADD_64 1
46 #define PMIX_HAVE_ATOMIC_AND_64 1
47 #define PMIX_HAVE_ATOMIC_OR_64 1
48 #define PMIX_HAVE_ATOMIC_XOR_64 1
49 #define PMIX_HAVE_ATOMIC_SUB_64 1
50
51 #define PMIX_HAVE_ATOMIC_LLSC_32 0
52 #define PMIX_HAVE_ATOMIC_LLSC_64 0
53 #define PMIX_HAVE_ATOMIC_LLSC_PTR 0
54
55 #define PMIX_HAVE_ATOMIC_MIN_32 1
56 #define PMIX_HAVE_ATOMIC_MAX_32 1
57
58 #define PMIX_HAVE_ATOMIC_MIN_64 1
59 #define PMIX_HAVE_ATOMIC_MAX_64 1
60
61 #define PMIX_HAVE_ATOMIC_SPINLOCKS 1
62
63 static inline void pmix_atomic_mb (void)
64 {
65 atomic_thread_fence (memory_order_seq_cst);
66 }
67
68 static inline void pmix_atomic_wmb (void)
69 {
70 atomic_thread_fence (memory_order_release);
71 }
72
73 static inline void pmix_atomic_rmb (void)
74 {
75 atomic_thread_fence (memory_order_acquire);
76 }
77
78 #define pmix_atomic_compare_exchange_strong_32(addr, compare, value) atomic_compare_exchange_strong_explicit (addr, compare, value, memory_order_relaxed, memory_order_relaxed)
79 #define pmix_atomic_compare_exchange_strong_64(addr, compare, value) atomic_compare_exchange_strong_explicit (addr, compare, value, memory_order_relaxed, memory_order_relaxed)
80 #define pmix_atomic_compare_exchange_strong_ptr(addr, compare, value) atomic_compare_exchange_strong_explicit (addr, compare, value, memory_order_relaxed, memory_order_relaxed)
81 #define pmix_atomic_compare_exchange_strong_acq_32(addr, compare, value) atomic_compare_exchange_strong_explicit (addr, compare, value, memory_order_acquire, memory_order_relaxed)
82 #define pmix_atomic_compare_exchange_strong_acq_64(addr, compare, value) atomic_compare_exchange_strong_explicit (addr, compare, value, memory_order_acquire, memory_order_relaxed)
83 #define pmix_atomic_compare_exchange_strong_acq_ptr(addr, compare, value) atomic_compare_exchange_strong_explicit (addr, compare, value, memory_order_acquire, memory_order_relaxed)
84
85 #define pmix_atomic_compare_exchange_strong_rel_32(addr, compare, value) atomic_compare_exchange_strong_explicit (addr, compare, value, memory_order_release, memory_order_relaxed)
86 #define pmix_atomic_compare_exchange_strong_rel_64(addr, compare, value) atomic_compare_exchange_strong_explicit (addr, compare, value, memory_order_release, memory_order_relaxed)
87 #define pmix_atomic_compare_exchange_strong_rel_ptr(addr, compare, value) atomic_compare_exchange_strong_explicit (addr, compare, value, memory_order_release, memory_order_relaxed)
88
89 #define pmix_atomic_compare_exchange_strong(addr, oldval, newval) atomic_compare_exchange_strong_explicit (addr, oldval, newval, memory_order_relaxed, memory_order_relaxed)
90 #define pmix_atomic_compare_exchange_strong_acq(addr, oldval, newval) atomic_compare_exchange_strong_explicit (addr, oldval, newval, memory_order_acquire, memory_order_relaxed)
91 #define pmix_atomic_compare_exchange_strong_rel(addr, oldval, newval) atomic_compare_exchange_strong_explicit (addr, oldval, newval, memory_order_release, memory_order_relaxed)
92
93 #define pmix_atomic_swap_32(addr, value) atomic_exchange_explicit (addr, value, memory_order_relaxed)
94 #define pmix_atomic_swap_64(addr, value) atomic_exchange_explicit (addr, value, memory_order_relaxed)
95 #define pmix_atomic_swap_ptr(addr, value) atomic_exchange_explicit (addr, value, memory_order_relaxed)
96
97 #define PMIX_ATOMIC_STDC_DEFINE_FETCH_OP(op, bits, type, operator) \
98 static inline type pmix_atomic_fetch_ ## op ##_## bits (pmix_atomic_ ## type *addr, type value) \
99 { \
100 return atomic_fetch_ ## op ## _explicit (addr, value, memory_order_relaxed); \
101 } \
102 \
103 static inline type pmix_atomic_## op ## _fetch_ ## bits (pmix_atomic_ ## type *addr, type value) \
104 { \
105 return atomic_fetch_ ## op ## _explicit (addr, value, memory_order_relaxed) operator value; \
106 }
107
108 PMIX_ATOMIC_STDC_DEFINE_FETCH_OP(add, 32, int32_t, +)
109 PMIX_ATOMIC_STDC_DEFINE_FETCH_OP(add, 64, int64_t, +)
110 PMIX_ATOMIC_STDC_DEFINE_FETCH_OP(add, size_t, size_t, +)
111
112 PMIX_ATOMIC_STDC_DEFINE_FETCH_OP(sub, 32, int32_t, -)
113 PMIX_ATOMIC_STDC_DEFINE_FETCH_OP(sub, 64, int64_t, -)
114 PMIX_ATOMIC_STDC_DEFINE_FETCH_OP(sub, size_t, size_t, -)
115
116 PMIX_ATOMIC_STDC_DEFINE_FETCH_OP(or, 32, int32_t, |)
117 PMIX_ATOMIC_STDC_DEFINE_FETCH_OP(or, 64, int64_t, |)
118
119 PMIX_ATOMIC_STDC_DEFINE_FETCH_OP(xor, 32, int32_t, ^)
120 PMIX_ATOMIC_STDC_DEFINE_FETCH_OP(xor, 64, int64_t, ^)
121
122 PMIX_ATOMIC_STDC_DEFINE_FETCH_OP(and, 32, int32_t, &)
123 PMIX_ATOMIC_STDC_DEFINE_FETCH_OP(and, 64, int64_t, &)
124
125 #define pmix_atomic_add(addr, value) (void) atomic_fetch_add_explicit (addr, value, memory_order_relaxed)
126
127 static inline int32_t pmix_atomic_fetch_min_32 (pmix_atomic_int32_t *addr, int32_t value)
128 {
129 int32_t old = *addr;
130 do {
131 if (old <= value) {
132 break;
133 }
134 } while (!pmix_atomic_compare_exchange_strong_32 (addr, &old, value));
135
136 return old;
137 }
138
139 static inline int32_t pmix_atomic_fetch_max_32 (pmix_atomic_int32_t *addr, int32_t value)
140 {
141 int32_t old = *addr;
142 do {
143 if (old >= value) {
144 break;
145 }
146 } while (!pmix_atomic_compare_exchange_strong_32 (addr, &old, value));
147
148 return old;
149 }
150
151 static inline int64_t pmix_atomic_fetch_min_64 (pmix_atomic_int64_t *addr, int64_t value)
152 {
153 int64_t old = *addr;
154 do {
155 if (old <= value) {
156 break;
157 }
158 } while (!pmix_atomic_compare_exchange_strong_64 (addr, &old, value));
159
160 return old;
161 }
162
163 static inline int64_t pmix_atomic_fetch_max_64 (pmix_atomic_int64_t *addr, int64_t value)
164 {
165 int64_t old = *addr;
166 do {
167 if (old >= value) {
168 break;
169 }
170 } while (!pmix_atomic_compare_exchange_strong_64 (addr, &old, value));
171
172 return old;
173 }
174
175 static inline int32_t pmix_atomic_min_fetch_32 (pmix_atomic_int32_t *addr, int32_t value)
176 {
177 int32_t old = pmix_atomic_fetch_min_32 (addr, value);
178 return old <= value ? old : value;
179 }
180
181 static inline int32_t pmix_atomic_max_fetch_32 (pmix_atomic_int32_t *addr, int32_t value)
182 {
183 int32_t old = pmix_atomic_fetch_max_32 (addr, value);
184 return old >= value ? old : value;
185 }
186
187 static inline int64_t pmix_atomic_min_fetch_64 (pmix_atomic_int64_t *addr, int64_t value)
188 {
189 int64_t old = pmix_atomic_fetch_min_64 (addr, value);
190 return old <= value ? old : value;
191 }
192
193 static inline int64_t pmix_atomic_max_fetch_64 (pmix_atomic_int64_t *addr, int64_t value)
194 {
195 int64_t old = pmix_atomic_fetch_max_64 (addr, value);
196 return old >= value ? old : value;
197 }
198
199 #define PMIX_ATOMIC_LOCK_UNLOCKED false
200 #define PMIX_ATOMIC_LOCK_LOCKED true
201
202 #define PMIX_ATOMIC_LOCK_INIT ATOMIC_FLAG_INIT
203
204 typedef atomic_flag pmix_atomic_lock_t;
205
206
207
208
209 static inline void pmix_atomic_lock_init (pmix_atomic_lock_t *lock, bool value)
210 {
211 atomic_flag_clear (lock);
212 }
213
214
215 static inline int pmix_atomic_trylock (pmix_atomic_lock_t *lock)
216 {
217 return (int) atomic_flag_test_and_set (lock);
218 }
219
220
221 static inline void pmix_atomic_lock(pmix_atomic_lock_t *lock)
222 {
223 while (pmix_atomic_trylock (lock)) {
224 }
225 }
226
227
228 static inline void pmix_atomic_unlock (pmix_atomic_lock_t *lock)
229 {
230 atomic_flag_clear (lock);
231 }
232
233
234 #if PMIX_HAVE_C11_CSWAP_INT128
235
236
237 #define pmix_atomic_compare_exchange_strong_128 atomic_compare_exchange_strong
238
239 #define PMIX_HAVE_ATOMIC_COMPARE_EXCHANGE_128 1
240
241 #elif PMIX_HAVE_SYNC_BUILTIN_CSWAP_INT128
242
243
244 __pmix_attribute_always_inline__
245 static inline bool pmix_atomic_compare_exchange_strong_128 (pmix_atomic_int128_t *addr,
246 pmix_int128_t *oldval, pmix_int128_t newval)
247 {
248 pmix_int128_t prev = __sync_val_compare_and_swap (addr, *oldval, newval);
249 bool ret = prev == *oldval;
250 *oldval = prev;
251 return ret;
252 }
253
254 #define PMIX_HAVE_ATOMIC_COMPARE_EXCHANGE_128 1
255
256 #else
257
258 #define PMIX_HAVE_ATOMIC_COMPARE_EXCHANGE_128 0
259
260 #endif
261
262 #endif