aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Chisnall <dchisnall@pathscale.com>2014-05-09 01:35:34 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2014-05-09 01:35:34 +0000
commitf66374f99bb19926d8e3bd8f969160830d801cb3 (patch)
treef621e5e998d30408b9a8c09f5e6fefd88a2b3cec
parent57ab7f59224ccdd747da9b8f1ca2827bcf6adf7c (diff)
parent3a3bee975842eac9c1e266bf7720f3891dd1516c (diff)
downloadlibcxxrt-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.h11
-rw-r--r--src/guard.cc11
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);
}