atomics: Add __nocheck atomic operations

While the check against sizeof(void *) is appropriate for
normal usage within qemu, there are places in which we want
wider operaions and have checked for their existance.

Reviewed-by: Emilio G. Cota <cota@braap.org>
Signed-off-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
Richard Henderson 2016-10-24 10:29:32 -07:00
parent 83d0c719f8
commit 84bca3927b
1 changed files with 27 additions and 9 deletions

View File

@ -99,15 +99,21 @@
* no effect on the generated code but not using the atomic primitives * no effect on the generated code but not using the atomic primitives
* will get flagged by sanitizers as a violation. * will get flagged by sanitizers as a violation.
*/ */
#define atomic_read__nocheck(ptr) \
__atomic_load_n(ptr, __ATOMIC_RELAXED)
#define atomic_read(ptr) \ #define atomic_read(ptr) \
({ \ ({ \
QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \ QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \
__atomic_load_n(ptr, __ATOMIC_RELAXED); \ atomic_read__nocheck(ptr); \
}) })
#define atomic_set__nocheck(ptr, i) \
__atomic_store_n(ptr, i, __ATOMIC_RELAXED)
#define atomic_set(ptr, i) do { \ #define atomic_set(ptr, i) do { \
QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \ QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \
__atomic_store_n(ptr, i, __ATOMIC_RELAXED); \ atomic_set__nocheck(ptr, i); \
} while(0) } while(0)
/* See above: most compilers currently treat consume and acquire the /* See above: most compilers currently treat consume and acquire the
@ -151,20 +157,27 @@
/* All the remaining operations are fully sequentially consistent */ /* All the remaining operations are fully sequentially consistent */
#define atomic_xchg__nocheck(ptr, i) ({ \
__atomic_exchange_n(ptr, (i), __ATOMIC_SEQ_CST); \
})
#define atomic_xchg(ptr, i) ({ \ #define atomic_xchg(ptr, i) ({ \
QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \ QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \
__atomic_exchange_n(ptr, i, __ATOMIC_SEQ_CST); \ atomic_xchg__nocheck(ptr, i); \
}) })
/* Returns the eventual value, failed or not */ /* Returns the eventual value, failed or not */
#define atomic_cmpxchg(ptr, old, new) \ #define atomic_cmpxchg__nocheck(ptr, old, new) ({ \
({ \
QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \
typeof_strip_qual(*ptr) _old = (old); \ typeof_strip_qual(*ptr) _old = (old); \
__atomic_compare_exchange_n(ptr, &_old, new, false, \ __atomic_compare_exchange_n(ptr, &_old, new, false, \
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); \ __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); \
_old; \ _old; \
}) })
#define atomic_cmpxchg(ptr, old, new) ({ \
QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \
atomic_cmpxchg__nocheck(ptr, old, new); \
})
/* Provide shorter names for GCC atomic builtins, return old value */ /* Provide shorter names for GCC atomic builtins, return old value */
#define atomic_fetch_inc(ptr) __atomic_fetch_add(ptr, 1, __ATOMIC_SEQ_CST) #define atomic_fetch_inc(ptr) __atomic_fetch_add(ptr, 1, __ATOMIC_SEQ_CST)
@ -279,8 +292,11 @@
/* These will only be atomic if the processor does the fetch or store /* These will only be atomic if the processor does the fetch or store
* in a single issue memory operation * in a single issue memory operation
*/ */
#define atomic_read(ptr) (*(__typeof__(*ptr) volatile*) (ptr)) #define atomic_read__nocheck(p) (*(__typeof__(*(p)) volatile*) (p))
#define atomic_set(ptr, i) ((*(__typeof__(*ptr) volatile*) (ptr)) = (i)) #define atomic_set__nocheck(p, i) ((*(__typeof__(*(p)) volatile*) (p)) = (i))
#define atomic_read(ptr) atomic_read__nocheck(ptr)
#define atomic_set(ptr, i) atomic_set__nocheck(ptr,i)
/** /**
* atomic_rcu_read - reads a RCU-protected pointer to a local variable * atomic_rcu_read - reads a RCU-protected pointer to a local variable
@ -341,6 +357,7 @@
#define atomic_xchg(ptr, i) (smp_mb(), __sync_lock_test_and_set(ptr, i)) #define atomic_xchg(ptr, i) (smp_mb(), __sync_lock_test_and_set(ptr, i))
#endif #endif
#endif #endif
#define atomic_xchg__nocheck atomic_xchg
/* Provide shorter names for GCC atomic builtins. */ /* Provide shorter names for GCC atomic builtins. */
#define atomic_fetch_inc(ptr) __sync_fetch_and_add(ptr, 1) #define atomic_fetch_inc(ptr) __sync_fetch_and_add(ptr, 1)
@ -360,6 +377,7 @@
#define atomic_xor_fetch(ptr, n) __sync_xor_and_fetch(ptr, n) #define atomic_xor_fetch(ptr, n) __sync_xor_and_fetch(ptr, n)
#define atomic_cmpxchg(ptr, old, new) __sync_val_compare_and_swap(ptr, old, new) #define atomic_cmpxchg(ptr, old, new) __sync_val_compare_and_swap(ptr, old, new)
#define atomic_cmpxchg__nocheck(ptr, old, new) atomic_cmpxchg(ptr, old, new)
/* And even shorter names that return void. */ /* And even shorter names that return void. */
#define atomic_inc(ptr) ((void) __sync_fetch_and_add(ptr, 1)) #define atomic_inc(ptr) ((void) __sync_fetch_and_add(ptr, 1))