diff options
author | David Chisnall <dchisnall@pathscale.com> | 2014-05-09 01:35:34 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-05-09 01:35:34 +0000 |
commit | f66374f99bb19926d8e3bd8f969160830d801cb3 (patch) | |
tree | f621e5e998d30408b9a8c09f5e6fefd88a2b3cec | |
parent | 57ab7f59224ccdd747da9b8f1ca2827bcf6adf7c (diff) | |
parent | 3a3bee975842eac9c1e266bf7720f3891dd1516c (diff) | |
download | libcxxrt-f66374f99bb19926d8e3bd8f969160830d801cb3.tar.gz |
am 3a3bee97: Add explicit store barriers when releasing locks.
* commit '3a3bee975842eac9c1e266bf7720f3891dd1516c':
Add explicit store barriers when releasing locks.
-rw-r--r-- | src/atomic.h | 11 | ||||
-rw-r--r-- | src/guard.cc | 11 |
2 files changed, 18 insertions, 4 deletions
diff --git a/src/atomic.h b/src/atomic.h index f68faf3..a3d2710 100644 --- a/src/atomic.h +++ b/src/atomic.h @@ -27,3 +27,14 @@ #define ATOMIC_LOAD(addr)\ (__sync_synchronize(), *addr) #endif + +#if __has_builtin(__c11_atomic_store) +#define ATOMIC_STORE(addr, value)\ + __c11_atomic_store((_Atomic(__typeof__(*addr))*)addr, value, __ATOMIC_RELEASE) +#else +#define ATOMIC_STORE(addr, value)\ + do {\ + *addr = value;\ + (__sync_synchronize(), *addr);\ + } while (0) +#endif diff --git a/src/guard.cc b/src/guard.cc index b14a13b..b350402 100644 --- a/src/guard.cc +++ b/src/guard.cc @@ -43,6 +43,7 @@ #include <stdint.h> #include <pthread.h> #include <assert.h> +#include "atomic.h" #ifdef __arm__ // ARM ABI - 32-bit guards. @@ -103,8 +104,8 @@ extern "C" void __cxa_guard_release(int32_t *guard_object) static int32_t *low_32_bits(volatile int64_t *ptr) { int32_t *low= (int32_t*)ptr; - // Test if the machine is big endian - constant propagation at compile time - // should eliminate this completely. + // Test if the machine is big endian - constant propagation at compile + // time should eliminate this completely. int one = 1; if (*(char*)&one != 1) { @@ -148,7 +149,7 @@ extern "C" int __cxa_guard_acquire(volatile int64_t *guard_object) extern "C" void __cxa_guard_abort(int64_t *guard_object) { int32_t *lock = low_32_bits(guard_object); - *lock = 0; + ATOMIC_STORE(lock, 0); } /** * Releases the guard and marks the object as initialised. This function is @@ -157,7 +158,9 @@ extern "C" void __cxa_guard_abort(int64_t *guard_object) extern "C" void __cxa_guard_release(int64_t *guard_object) { // Set the first byte to 1 - *guard_object |= ((int64_t)1) << 56; + // Note: We don't do an atomic load here because getting a stale value + // is not a problem in the current implementation. + ATOMIC_STORE(guard_object, (*guard_object | ((int64_t)1) << 56)); __cxa_guard_abort(guard_object); } |