#endif
/* xchg */
+
+/*
+ * If the toolchain supports the C11 memory model, then it is safe to implement
+ * `uatomic_xchg()' in term of __atomic builtins. This has the effect of
+ * reducing the number of emitted memory barriers except for the
+ * CMM_SEQ_CST_FENCE memory order.
+ */
+#ifdef _CMM_TOOLCHAIN_SUPPORT_C11_MM
+# define uatomic_xchg_mo(addr, v, mo) \
+ __extension__ \
+ ({ \
+ __typeof__((*addr)) _old = \
+ __atomic_exchange_n(cmm_cast_volatile(addr), v, \
+ cmm_to_c11(mo)); \
+ cmm_seq_cst_fence_after_atomic(mo); \
+ _old; \
+ })
+#else
+
static inline void _cmm_compat_c11_smp_mb__before_xchg_mo(enum cmm_memorder mo)
{
switch (mo) {
*
* [1] https://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html
*/
-#define uatomic_xchg_mo(addr, v, mo) \
+# define uatomic_xchg_mo(addr, v, mo) \
({ \
_cmm_compat_c11_smp_mb__before_xchg_mo(mo); \
__sync_lock_test_and_set(addr, v); \
})
+#endif /* _CMM_TOOLCHAIN_SUPPORT_C11_MM */
#ifdef __cplusplus
}