]>
Commit | Line | Data |
---|---|---|
5444e768 PB |
1 | /* |
2 | * Simple interface for atomic operations. | |
3 | * | |
4 | * Copyright (C) 2013 Red Hat, Inc. | |
5 | * | |
6 | * Author: Paolo Bonzini <[email protected]> | |
7 | * | |
8 | * This work is licensed under the terms of the GNU GPL, version 2 or later. | |
9 | * See the COPYING file in the top-level directory. | |
10 | * | |
b208ac07 | 11 | * See docs/devel/atomics.txt for discussion about the guarantees each |
a0aa44b4 | 12 | * atomic primitive is meant to provide. |
5444e768 | 13 | */ |
85199474 | 14 | |
2a6a4076 MA |
15 | #ifndef QEMU_ATOMIC_H |
16 | #define QEMU_ATOMIC_H | |
1d31fca4 | 17 | |
5444e768 PB |
18 | /* Compiler barrier */ |
19 | #define barrier() ({ asm volatile("" ::: "memory"); (void)0; }) | |
20 | ||
5927ed84 PB |
21 | /* The variable that receives the old value of an atomically-accessed |
22 | * variable must be non-qualified, because atomic builtins return values | |
23 | * through a pointer-type argument as in __atomic_load(&var, &old, MODEL). | |
24 | * | |
25 | * This macro has to handle types smaller than int manually, because of | |
26 | * implicit promotion. int and larger types, as well as pointers, can be | |
27 | * converted to a non-qualified type just by applying a binary operator. | |
28 | */ | |
29 | #define typeof_strip_qual(expr) \ | |
30 | typeof( \ | |
31 | __builtin_choose_expr( \ | |
32 | __builtin_types_compatible_p(typeof(expr), bool) || \ | |
33 | __builtin_types_compatible_p(typeof(expr), const bool) || \ | |
34 | __builtin_types_compatible_p(typeof(expr), volatile bool) || \ | |
35 | __builtin_types_compatible_p(typeof(expr), const volatile bool), \ | |
36 | (bool)1, \ | |
37 | __builtin_choose_expr( \ | |
38 | __builtin_types_compatible_p(typeof(expr), signed char) || \ | |
39 | __builtin_types_compatible_p(typeof(expr), const signed char) || \ | |
40 | __builtin_types_compatible_p(typeof(expr), volatile signed char) || \ | |
41 | __builtin_types_compatible_p(typeof(expr), const volatile signed char), \ | |
42 | (signed char)1, \ | |
43 | __builtin_choose_expr( \ | |
44 | __builtin_types_compatible_p(typeof(expr), unsigned char) || \ | |
45 | __builtin_types_compatible_p(typeof(expr), const unsigned char) || \ | |
46 | __builtin_types_compatible_p(typeof(expr), volatile unsigned char) || \ | |
47 | __builtin_types_compatible_p(typeof(expr), const volatile unsigned char), \ | |
48 | (unsigned char)1, \ | |
49 | __builtin_choose_expr( \ | |
50 | __builtin_types_compatible_p(typeof(expr), signed short) || \ | |
51 | __builtin_types_compatible_p(typeof(expr), const signed short) || \ | |
52 | __builtin_types_compatible_p(typeof(expr), volatile signed short) || \ | |
53 | __builtin_types_compatible_p(typeof(expr), const volatile signed short), \ | |
54 | (signed short)1, \ | |
55 | __builtin_choose_expr( \ | |
56 | __builtin_types_compatible_p(typeof(expr), unsigned short) || \ | |
57 | __builtin_types_compatible_p(typeof(expr), const unsigned short) || \ | |
58 | __builtin_types_compatible_p(typeof(expr), volatile unsigned short) || \ | |
59 | __builtin_types_compatible_p(typeof(expr), const volatile unsigned short), \ | |
60 | (unsigned short)1, \ | |
61 | (expr)+0)))))) | |
62 | ||
a0aa44b4 AB |
63 | #ifdef __ATOMIC_RELAXED |
64 | /* For C11 atomic ops */ | |
65 | ||
66 | /* Manual memory barriers | |
67 | * | |
68 | *__atomic_thread_fence does not include a compiler barrier; instead, | |
69 | * the barrier is part of __atomic_load/__atomic_store's "volatile-like" | |
70 | * semantics. If smp_wmb() is a no-op, absence of the barrier means that | |
71 | * the compiler is free to reorder stores on each side of the barrier. | |
72 | * Add one here, and similarly in smp_rmb() and smp_read_barrier_depends(). | |
73 | */ | |
74 | ||
f1ee8696 PB |
75 | #define smp_mb() ({ barrier(); __atomic_thread_fence(__ATOMIC_SEQ_CST); }) |
76 | #define smp_mb_release() ({ barrier(); __atomic_thread_fence(__ATOMIC_RELEASE); }) | |
77 | #define smp_mb_acquire() ({ barrier(); __atomic_thread_fence(__ATOMIC_ACQUIRE); }) | |
a0aa44b4 | 78 | |
c9838952 EC |
79 | /* Most compilers currently treat consume and acquire the same, but really |
80 | * no processors except Alpha need a barrier here. Leave it in if | |
81 | * using Thread Sanitizer to avoid warnings, otherwise optimize it away. | |
82 | */ | |
83 | #if defined(__SANITIZE_THREAD__) | |
f1ee8696 | 84 | #define smp_read_barrier_depends() ({ barrier(); __atomic_thread_fence(__ATOMIC_CONSUME); }) |
23ea7f57 | 85 | #elif defined(__alpha__) |
c9838952 EC |
86 | #define smp_read_barrier_depends() asm volatile("mb":::"memory") |
87 | #else | |
88 | #define smp_read_barrier_depends() barrier() | |
89 | #endif | |
90 | ||
374aae65 RH |
91 | /* Sanity check that the size of an atomic operation isn't "overly large". |
92 | * Despite the fact that e.g. i686 has 64-bit atomic operations, we do not | |
93 | * want to use them because we ought not need them, and this lets us do a | |
94 | * bit of sanity checking that other 32-bit hosts might build. | |
95 | * | |
96 | * That said, we have a problem on 64-bit ILP32 hosts in that in order to | |
97 | * sync with TCG_OVERSIZED_GUEST, this must match TCG_TARGET_REG_BITS. | |
98 | * We'd prefer not want to pull in everything else TCG related, so handle | |
99 | * those few cases by hand. | |
100 | * | |
119c440c | 101 | * Note that x32 is fully detected with __x86_64__ + _ILP32, and that for |
c5b00c16 PB |
102 | * Sparc we always force the use of sparcv9 in configure. MIPS n32 (ILP32) & |
103 | * n64 (LP64) ABIs are both detected using __mips64. | |
374aae65 | 104 | */ |
c5b00c16 | 105 | #if defined(__x86_64__) || defined(__sparc__) || defined(__mips64) |
374aae65 RH |
106 | # define ATOMIC_REG_SIZE 8 |
107 | #else | |
108 | # define ATOMIC_REG_SIZE sizeof(void *) | |
109 | #endif | |
a0aa44b4 AB |
110 | |
111 | /* Weak atomic operations prevent the compiler moving other | |
112 | * loads/stores past the atomic operation load/store. However there is | |
113 | * no explicit memory barrier for the processor. | |
e653bc6b AB |
114 | * |
115 | * The C11 memory model says that variables that are accessed from | |
116 | * different threads should at least be done with __ATOMIC_RELAXED | |
117 | * primitives or the result is undefined. Generally this has little to | |
118 | * no effect on the generated code but not using the atomic primitives | |
119 | * will get flagged by sanitizers as a violation. | |
a0aa44b4 | 120 | */ |
84bca392 RH |
121 | #define atomic_read__nocheck(ptr) \ |
122 | __atomic_load_n(ptr, __ATOMIC_RELAXED) | |
123 | ||
ca47a926 AB |
124 | #define atomic_read(ptr) \ |
125 | ({ \ | |
374aae65 | 126 | QEMU_BUILD_BUG_ON(sizeof(*ptr) > ATOMIC_REG_SIZE); \ |
84bca392 | 127 | atomic_read__nocheck(ptr); \ |
a0aa44b4 AB |
128 | }) |
129 | ||
84bca392 RH |
130 | #define atomic_set__nocheck(ptr, i) \ |
131 | __atomic_store_n(ptr, i, __ATOMIC_RELAXED) | |
132 | ||
ca47a926 | 133 | #define atomic_set(ptr, i) do { \ |
374aae65 | 134 | QEMU_BUILD_BUG_ON(sizeof(*ptr) > ATOMIC_REG_SIZE); \ |
84bca392 | 135 | atomic_set__nocheck(ptr, i); \ |
a0aa44b4 AB |
136 | } while(0) |
137 | ||
15487aa1 EC |
138 | /* See above: most compilers currently treat consume and acquire the |
139 | * same, but this slows down atomic_rcu_read unnecessarily. | |
140 | */ | |
141 | #ifdef __SANITIZE_THREAD__ | |
142 | #define atomic_rcu_read__nocheck(ptr, valptr) \ | |
143 | __atomic_load(ptr, valptr, __ATOMIC_CONSUME); | |
144 | #else | |
145 | #define atomic_rcu_read__nocheck(ptr, valptr) \ | |
146 | __atomic_load(ptr, valptr, __ATOMIC_RELAXED); \ | |
147 | smp_read_barrier_depends(); | |
148 | #endif | |
a0aa44b4 | 149 | |
ca47a926 AB |
150 | #define atomic_rcu_read(ptr) \ |
151 | ({ \ | |
374aae65 | 152 | QEMU_BUILD_BUG_ON(sizeof(*ptr) > ATOMIC_REG_SIZE); \ |
5927ed84 | 153 | typeof_strip_qual(*ptr) _val; \ |
15487aa1 | 154 | atomic_rcu_read__nocheck(ptr, &_val); \ |
ca47a926 | 155 | _val; \ |
a0aa44b4 AB |
156 | }) |
157 | ||
ca47a926 | 158 | #define atomic_rcu_set(ptr, i) do { \ |
374aae65 | 159 | QEMU_BUILD_BUG_ON(sizeof(*ptr) > ATOMIC_REG_SIZE); \ |
89943de1 | 160 | __atomic_store_n(ptr, i, __ATOMIC_RELEASE); \ |
a0aa44b4 AB |
161 | } while(0) |
162 | ||
803cf26a | 163 | #define atomic_load_acquire(ptr) \ |
a0aa44b4 | 164 | ({ \ |
374aae65 | 165 | QEMU_BUILD_BUG_ON(sizeof(*ptr) > ATOMIC_REG_SIZE); \ |
5927ed84 | 166 | typeof_strip_qual(*ptr) _val; \ |
803cf26a | 167 | __atomic_load(ptr, &_val, __ATOMIC_ACQUIRE); \ |
a0aa44b4 AB |
168 | _val; \ |
169 | }) | |
170 | ||
803cf26a | 171 | #define atomic_store_release(ptr, i) do { \ |
374aae65 | 172 | QEMU_BUILD_BUG_ON(sizeof(*ptr) > ATOMIC_REG_SIZE); \ |
803cf26a | 173 | __atomic_store_n(ptr, i, __ATOMIC_RELEASE); \ |
a0aa44b4 | 174 | } while(0) |
a0aa44b4 AB |
175 | |
176 | ||
177 | /* All the remaining operations are fully sequentially consistent */ | |
178 | ||
84bca392 RH |
179 | #define atomic_xchg__nocheck(ptr, i) ({ \ |
180 | __atomic_exchange_n(ptr, (i), __ATOMIC_SEQ_CST); \ | |
181 | }) | |
182 | ||
a0aa44b4 | 183 | #define atomic_xchg(ptr, i) ({ \ |
374aae65 | 184 | QEMU_BUILD_BUG_ON(sizeof(*ptr) > ATOMIC_REG_SIZE); \ |
84bca392 | 185 | atomic_xchg__nocheck(ptr, i); \ |
a0aa44b4 AB |
186 | }) |
187 | ||
188 | /* Returns the eventual value, failed or not */ | |
84bca392 | 189 | #define atomic_cmpxchg__nocheck(ptr, old, new) ({ \ |
89943de1 | 190 | typeof_strip_qual(*ptr) _old = (old); \ |
cd95fc28 | 191 | (void)__atomic_compare_exchange_n(ptr, &_old, new, false, \ |
a0aa44b4 AB |
192 | __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); \ |
193 | _old; \ | |
84bca392 RH |
194 | }) |
195 | ||
196 | #define atomic_cmpxchg(ptr, old, new) ({ \ | |
374aae65 | 197 | QEMU_BUILD_BUG_ON(sizeof(*ptr) > ATOMIC_REG_SIZE); \ |
84bca392 RH |
198 | atomic_cmpxchg__nocheck(ptr, old, new); \ |
199 | }) | |
a0aa44b4 AB |
200 | |
201 | /* Provide shorter names for GCC atomic builtins, return old value */ | |
202 | #define atomic_fetch_inc(ptr) __atomic_fetch_add(ptr, 1, __ATOMIC_SEQ_CST) | |
203 | #define atomic_fetch_dec(ptr) __atomic_fetch_sub(ptr, 1, __ATOMIC_SEQ_CST) | |
204 | #define atomic_fetch_add(ptr, n) __atomic_fetch_add(ptr, n, __ATOMIC_SEQ_CST) | |
205 | #define atomic_fetch_sub(ptr, n) __atomic_fetch_sub(ptr, n, __ATOMIC_SEQ_CST) | |
206 | #define atomic_fetch_and(ptr, n) __atomic_fetch_and(ptr, n, __ATOMIC_SEQ_CST) | |
207 | #define atomic_fetch_or(ptr, n) __atomic_fetch_or(ptr, n, __ATOMIC_SEQ_CST) | |
61696ddb | 208 | #define atomic_fetch_xor(ptr, n) __atomic_fetch_xor(ptr, n, __ATOMIC_SEQ_CST) |
a0aa44b4 | 209 | |
83d0c719 EC |
210 | #define atomic_inc_fetch(ptr) __atomic_add_fetch(ptr, 1, __ATOMIC_SEQ_CST) |
211 | #define atomic_dec_fetch(ptr) __atomic_sub_fetch(ptr, 1, __ATOMIC_SEQ_CST) | |
212 | #define atomic_add_fetch(ptr, n) __atomic_add_fetch(ptr, n, __ATOMIC_SEQ_CST) | |
213 | #define atomic_sub_fetch(ptr, n) __atomic_sub_fetch(ptr, n, __ATOMIC_SEQ_CST) | |
214 | #define atomic_and_fetch(ptr, n) __atomic_and_fetch(ptr, n, __ATOMIC_SEQ_CST) | |
215 | #define atomic_or_fetch(ptr, n) __atomic_or_fetch(ptr, n, __ATOMIC_SEQ_CST) | |
216 | #define atomic_xor_fetch(ptr, n) __atomic_xor_fetch(ptr, n, __ATOMIC_SEQ_CST) | |
217 | ||
a0aa44b4 AB |
218 | /* And even shorter names that return void. */ |
219 | #define atomic_inc(ptr) ((void) __atomic_fetch_add(ptr, 1, __ATOMIC_SEQ_CST)) | |
220 | #define atomic_dec(ptr) ((void) __atomic_fetch_sub(ptr, 1, __ATOMIC_SEQ_CST)) | |
221 | #define atomic_add(ptr, n) ((void) __atomic_fetch_add(ptr, n, __ATOMIC_SEQ_CST)) | |
222 | #define atomic_sub(ptr, n) ((void) __atomic_fetch_sub(ptr, n, __ATOMIC_SEQ_CST)) | |
223 | #define atomic_and(ptr, n) ((void) __atomic_fetch_and(ptr, n, __ATOMIC_SEQ_CST)) | |
224 | #define atomic_or(ptr, n) ((void) __atomic_fetch_or(ptr, n, __ATOMIC_SEQ_CST)) | |
61696ddb | 225 | #define atomic_xor(ptr, n) ((void) __atomic_fetch_xor(ptr, n, __ATOMIC_SEQ_CST)) |
a0aa44b4 AB |
226 | |
227 | #else /* __ATOMIC_RELAXED */ | |
52e850de | 228 | |
a281ebc1 | 229 | /* |
5444e768 PB |
230 | * We use GCC builtin if it's available, as that can use mfence on |
231 | * 32-bit as well, e.g. if built with -march=pentium-m. However, on | |
232 | * i386 the spec is buggy, and the implementation followed it until | |
233 | * 4.3 (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36793). | |
234 | */ | |
235 | #if defined(__i386__) || defined(__x86_64__) | |
236 | #if !QEMU_GNUC_PREREQ(4, 4) | |
237 | #if defined __x86_64__ | |
238 | #define smp_mb() ({ asm volatile("mfence" ::: "memory"); (void)0; }) | |
a281ebc1 | 239 | #else |
5444e768 PB |
240 | #define smp_mb() ({ asm volatile("lock; addl $0,0(%%esp) " ::: "memory"); (void)0; }) |
241 | #endif | |
242 | #endif | |
243 | #endif | |
244 | ||
245 | ||
246 | #ifdef __alpha__ | |
247 | #define smp_read_barrier_depends() asm volatile("mb":::"memory") | |
a281ebc1 MT |
248 | #endif |
249 | ||
5444e768 | 250 | #if defined(__i386__) || defined(__x86_64__) || defined(__s390x__) |
a281ebc1 | 251 | |
5444e768 PB |
252 | /* |
253 | * Because of the strongly ordered storage model, wmb() and rmb() are nops | |
254 | * here (a compiler barrier only). QEMU doesn't do accesses to write-combining | |
255 | * qemu memory or non-temporal load/stores from C code. | |
256 | */ | |
f1ee8696 PB |
257 | #define smp_mb_release() barrier() |
258 | #define smp_mb_acquire() barrier() | |
5444e768 PB |
259 | |
260 | /* | |
261 | * __sync_lock_test_and_set() is documented to be an acquire barrier only, | |
262 | * but it is a full barrier at the hardware level. Add a compiler barrier | |
263 | * to make it a full barrier also at the compiler level. | |
264 | */ | |
265 | #define atomic_xchg(ptr, i) (barrier(), __sync_lock_test_and_set(ptr, i)) | |
266 | ||
463ce4ae | 267 | #elif defined(_ARCH_PPC) |
e2251708 DG |
268 | |
269 | /* | |
a281ebc1 | 270 | * We use an eieio() for wmb() on powerpc. This assumes we don't |
e2251708 | 271 | * need to order cacheable and non-cacheable stores with respect to |
5444e768 PB |
272 | * each other. |
273 | * | |
274 | * smp_mb has the same problem as on x86 for not-very-new GCC | |
275 | * (http://patchwork.ozlabs.org/patch/126184/, Nov 2011). | |
e2251708 | 276 | */ |
f1ee8696 | 277 | #define smp_wmb() ({ asm volatile("eieio" ::: "memory"); (void)0; }) |
a821ce59 | 278 | #if defined(__powerpc64__) |
f1ee8696 PB |
279 | #define smp_mb_release() ({ asm volatile("lwsync" ::: "memory"); (void)0; }) |
280 | #define smp_mb_acquire() ({ asm volatile("lwsync" ::: "memory"); (void)0; }) | |
a821ce59 | 281 | #else |
f1ee8696 PB |
282 | #define smp_mb_release() ({ asm volatile("sync" ::: "memory"); (void)0; }) |
283 | #define smp_mb_acquire() ({ asm volatile("sync" ::: "memory"); (void)0; }) | |
a821ce59 | 284 | #endif |
f1ee8696 | 285 | #define smp_mb() ({ asm volatile("sync" ::: "memory"); (void)0; }) |
a821ce59 | 286 | |
5444e768 | 287 | #endif /* _ARCH_PPC */ |
e2251708 | 288 | |
e2251708 DG |
289 | /* |
290 | * For (host) platforms we don't have explicit barrier definitions | |
291 | * for, we use the gcc __sync_synchronize() primitive to generate a | |
292 | * full barrier. This should be safe on all platforms, though it may | |
f1ee8696 | 293 | * be overkill for smp_mb_acquire() and smp_mb_release(). |
e2251708 | 294 | */ |
5444e768 | 295 | #ifndef smp_mb |
f1ee8696 | 296 | #define smp_mb() __sync_synchronize() |
5444e768 PB |
297 | #endif |
298 | ||
f1ee8696 PB |
299 | #ifndef smp_mb_acquire |
300 | #define smp_mb_acquire() __sync_synchronize() | |
5444e768 | 301 | #endif |
5444e768 | 302 | |
f1ee8696 PB |
303 | #ifndef smp_mb_release |
304 | #define smp_mb_release() __sync_synchronize() | |
5444e768 | 305 | #endif |
5444e768 PB |
306 | |
307 | #ifndef smp_read_barrier_depends | |
5444e768 PB |
308 | #define smp_read_barrier_depends() barrier() |
309 | #endif | |
e2251708 | 310 | |
a0aa44b4 AB |
311 | /* These will only be atomic if the processor does the fetch or store |
312 | * in a single issue memory operation | |
313 | */ | |
84bca392 RH |
314 | #define atomic_read__nocheck(p) (*(__typeof__(*(p)) volatile*) (p)) |
315 | #define atomic_set__nocheck(p, i) ((*(__typeof__(*(p)) volatile*) (p)) = (i)) | |
316 | ||
317 | #define atomic_read(ptr) atomic_read__nocheck(ptr) | |
318 | #define atomic_set(ptr, i) atomic_set__nocheck(ptr,i) | |
5444e768 | 319 | |
7911747b PB |
320 | /** |
321 | * atomic_rcu_read - reads a RCU-protected pointer to a local variable | |
322 | * into a RCU read-side critical section. The pointer can later be safely | |
323 | * dereferenced within the critical section. | |
324 | * | |
325 | * This ensures that the pointer copy is invariant thorough the whole critical | |
326 | * section. | |
327 | * | |
328 | * Inserts memory barriers on architectures that require them (currently only | |
329 | * Alpha) and documents which pointers are protected by RCU. | |
330 | * | |
a0aa44b4 AB |
331 | * atomic_rcu_read also includes a compiler barrier to ensure that |
332 | * value-speculative optimizations (e.g. VSS: Value Speculation | |
333 | * Scheduling) does not perform the data read before the pointer read | |
334 | * by speculating the value of the pointer. | |
7911747b PB |
335 | * |
336 | * Should match atomic_rcu_set(), atomic_xchg(), atomic_cmpxchg(). | |
337 | */ | |
7911747b PB |
338 | #define atomic_rcu_read(ptr) ({ \ |
339 | typeof(*ptr) _val = atomic_read(ptr); \ | |
340 | smp_read_barrier_depends(); \ | |
341 | _val; \ | |
342 | }) | |
7911747b PB |
343 | |
344 | /** | |
345 | * atomic_rcu_set - assigns (publicizes) a pointer to a new data structure | |
346 | * meant to be read by RCU read-side critical sections. | |
347 | * | |
348 | * Documents which pointers will be dereferenced by RCU read-side critical | |
349 | * sections and adds the required memory barriers on architectures requiring | |
350 | * them. It also makes sure the compiler does not reorder code initializing the | |
351 | * data structure before its publication. | |
352 | * | |
353 | * Should match atomic_rcu_read(). | |
354 | */ | |
7911747b PB |
355 | #define atomic_rcu_set(ptr, i) do { \ |
356 | smp_wmb(); \ | |
357 | atomic_set(ptr, i); \ | |
358 | } while (0) | |
7911747b | 359 | |
803cf26a | 360 | #define atomic_load_acquire(ptr) ({ \ |
5444e768 | 361 | typeof(*ptr) _val = atomic_read(ptr); \ |
f1ee8696 | 362 | smp_mb_acquire(); \ |
5444e768 PB |
363 | _val; \ |
364 | }) | |
5444e768 | 365 | |
803cf26a | 366 | #define atomic_store_release(ptr, i) do { \ |
f1ee8696 | 367 | smp_mb_release(); \ |
5444e768 | 368 | atomic_set(ptr, i); \ |
5444e768 | 369 | } while (0) |
5444e768 PB |
370 | |
371 | #ifndef atomic_xchg | |
33effd3a PM |
372 | #if defined(__clang__) |
373 | #define atomic_xchg(ptr, i) __sync_swap(ptr, i) | |
5444e768 PB |
374 | #else |
375 | /* __sync_lock_test_and_set() is documented to be an acquire barrier only. */ | |
376 | #define atomic_xchg(ptr, i) (smp_mb(), __sync_lock_test_and_set(ptr, i)) | |
377 | #endif | |
378 | #endif | |
84bca392 | 379 | #define atomic_xchg__nocheck atomic_xchg |
5444e768 PB |
380 | |
381 | /* Provide shorter names for GCC atomic builtins. */ | |
382 | #define atomic_fetch_inc(ptr) __sync_fetch_and_add(ptr, 1) | |
383 | #define atomic_fetch_dec(ptr) __sync_fetch_and_add(ptr, -1) | |
d1a9f2d1 RH |
384 | #define atomic_fetch_add(ptr, n) __sync_fetch_and_add(ptr, n) |
385 | #define atomic_fetch_sub(ptr, n) __sync_fetch_and_sub(ptr, n) | |
386 | #define atomic_fetch_and(ptr, n) __sync_fetch_and_and(ptr, n) | |
387 | #define atomic_fetch_or(ptr, n) __sync_fetch_and_or(ptr, n) | |
61696ddb | 388 | #define atomic_fetch_xor(ptr, n) __sync_fetch_and_xor(ptr, n) |
83d0c719 EC |
389 | |
390 | #define atomic_inc_fetch(ptr) __sync_add_and_fetch(ptr, 1) | |
391 | #define atomic_dec_fetch(ptr) __sync_add_and_fetch(ptr, -1) | |
392 | #define atomic_add_fetch(ptr, n) __sync_add_and_fetch(ptr, n) | |
393 | #define atomic_sub_fetch(ptr, n) __sync_sub_and_fetch(ptr, n) | |
394 | #define atomic_and_fetch(ptr, n) __sync_and_and_fetch(ptr, n) | |
395 | #define atomic_or_fetch(ptr, n) __sync_or_and_fetch(ptr, n) | |
396 | #define atomic_xor_fetch(ptr, n) __sync_xor_and_fetch(ptr, n) | |
397 | ||
d1a9f2d1 | 398 | #define atomic_cmpxchg(ptr, old, new) __sync_val_compare_and_swap(ptr, old, new) |
84bca392 | 399 | #define atomic_cmpxchg__nocheck(ptr, old, new) atomic_cmpxchg(ptr, old, new) |
5444e768 PB |
400 | |
401 | /* And even shorter names that return void. */ | |
402 | #define atomic_inc(ptr) ((void) __sync_fetch_and_add(ptr, 1)) | |
403 | #define atomic_dec(ptr) ((void) __sync_fetch_and_add(ptr, -1)) | |
404 | #define atomic_add(ptr, n) ((void) __sync_fetch_and_add(ptr, n)) | |
405 | #define atomic_sub(ptr, n) ((void) __sync_fetch_and_sub(ptr, n)) | |
406 | #define atomic_and(ptr, n) ((void) __sync_fetch_and_and(ptr, n)) | |
407 | #define atomic_or(ptr, n) ((void) __sync_fetch_and_or(ptr, n)) | |
61696ddb | 408 | #define atomic_xor(ptr, n) ((void) __sync_fetch_and_xor(ptr, n)) |
5444e768 | 409 | |
a0aa44b4 | 410 | #endif /* __ATOMIC_RELAXED */ |
f1ee8696 PB |
411 | |
412 | #ifndef smp_wmb | |
413 | #define smp_wmb() smp_mb_release() | |
414 | #endif | |
415 | #ifndef smp_rmb | |
416 | #define smp_rmb() smp_mb_acquire() | |
417 | #endif | |
418 | ||
803cf26a PB |
419 | /* This is more efficient than a store plus a fence. */ |
420 | #if !defined(__SANITIZE_THREAD__) | |
421 | #if defined(__i386__) || defined(__x86_64__) || defined(__s390x__) | |
422 | #define atomic_mb_set(ptr, i) ((void)atomic_xchg(ptr, i)) | |
423 | #endif | |
424 | #endif | |
425 | ||
426 | /* atomic_mb_read/set semantics map Java volatile variables. They are | |
427 | * less expensive on some platforms (notably POWER) than fully | |
428 | * sequentially consistent operations. | |
429 | * | |
430 | * As long as they are used as paired operations they are safe to | |
b208ac07 | 431 | * use. See docs/devel/atomics.txt for more discussion. |
803cf26a PB |
432 | */ |
433 | ||
434 | #ifndef atomic_mb_read | |
435 | #define atomic_mb_read(ptr) \ | |
436 | atomic_load_acquire(ptr) | |
437 | #endif | |
438 | ||
439 | #ifndef atomic_mb_set | |
440 | #define atomic_mb_set(ptr, i) do { \ | |
441 | atomic_store_release(ptr, i); \ | |
442 | smp_mb(); \ | |
443 | } while(0) | |
444 | #endif | |
445 | ||
447b0d0b PB |
446 | #define atomic_fetch_inc_nonzero(ptr) ({ \ |
447 | typeof_strip_qual(*ptr) _oldn = atomic_read(ptr); \ | |
448 | while (_oldn && atomic_cmpxchg(ptr, _oldn, _oldn + 1) != _oldn) { \ | |
449 | _oldn = atomic_read(ptr); \ | |
450 | } \ | |
451 | _oldn; \ | |
452 | }) | |
453 | ||
782da5b2 EC |
454 | /* Abstractions to access atomically (i.e. "once") i64/u64 variables */ |
455 | #ifdef CONFIG_ATOMIC64 | |
456 | static inline int64_t atomic_read_i64(const int64_t *ptr) | |
457 | { | |
458 | /* use __nocheck because sizeof(void *) might be < sizeof(u64) */ | |
459 | return atomic_read__nocheck(ptr); | |
460 | } | |
461 | ||
462 | static inline uint64_t atomic_read_u64(const uint64_t *ptr) | |
463 | { | |
464 | return atomic_read__nocheck(ptr); | |
465 | } | |
466 | ||
467 | static inline void atomic_set_i64(int64_t *ptr, int64_t val) | |
468 | { | |
469 | atomic_set__nocheck(ptr, val); | |
470 | } | |
471 | ||
472 | static inline void atomic_set_u64(uint64_t *ptr, uint64_t val) | |
473 | { | |
474 | atomic_set__nocheck(ptr, val); | |
475 | } | |
476 | ||
477 | static inline void atomic64_init(void) | |
478 | { | |
479 | } | |
480 | #else /* !CONFIG_ATOMIC64 */ | |
481 | int64_t atomic_read_i64(const int64_t *ptr); | |
482 | uint64_t atomic_read_u64(const uint64_t *ptr); | |
483 | void atomic_set_i64(int64_t *ptr, int64_t val); | |
484 | void atomic_set_u64(uint64_t *ptr, uint64_t val); | |
485 | void atomic64_init(void); | |
486 | #endif /* !CONFIG_ATOMIC64 */ | |
487 | ||
2a6a4076 | 488 | #endif /* QEMU_ATOMIC_H */ |