From: Mathieu Desnoyers Date: Mon, 5 Dec 2016 14:35:34 +0000 (-0500) Subject: Fix: uatomic arm32: add missing release barrier before uatomic_xchg X-Git-Tag: v0.10.0~15 X-Git-Url: http://git.liburcu.org/?p=urcu.git;a=commitdiff_plain;h=c278ffc739374fbcc6d2fb35eca26b57da4c6447;hp=e9bea64ae432ec3cdd6d2ccbd691190a35256d97 Fix: uatomic arm32: add missing release barrier before uatomic_xchg __sync_lock_test_and_set() only imply a release barrier, but uatomic_xchg() guarantees both acquire and release barrier semantics. Therefore, add the missing release barrier. Signed-off-by: Mathieu Desnoyers --- diff --git a/include/urcu/uatomic/arm.h b/include/urcu/uatomic/arm.h index fd8fe6a..95f32f3 100644 --- a/include/urcu/uatomic/arm.h +++ b/include/urcu/uatomic/arm.h @@ -26,13 +26,27 @@ #include #include +#include #ifdef __cplusplus extern "C" { #endif /* xchg */ -#define uatomic_xchg(addr, v) __sync_lock_test_and_set(addr, v) + +/* + * Based on [1], __sync_lock_test_and_set() is not a full barrier, but + * instead only an acquire barrier. Given that uatomic_xchg() acts as + * both release and acquire barriers, we therefore need to have our own + * release barrier before this operation. + * + * [1] https://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html + */ +#define uatomic_xchg(addr, v) \ + ({ \ + cmm_smp_mb(); \ + __sync_lock_test_and_set(addr, v); \ + }) #ifdef __cplusplus }