Index: Source/wtf/Atomics.h |
diff --git a/Source/wtf/Atomics.h b/Source/wtf/Atomics.h |
index 8ac6d9baade474c310446574612d1d27ef4a8bc3..4605c0786916d1bb505a63f11fedcec3420a8c86 100644 |
--- a/Source/wtf/Atomics.h |
+++ b/Source/wtf/Atomics.h |
@@ -31,6 +31,7 @@ |
#define Atomics_h |
#include "wtf/Assertions.h" |
+#include "wtf/CPU.h" |
#include <stdint.h> |
@@ -38,6 +39,10 @@ |
#include <windows.h> |
#endif |
+#if defined(THREAD_SANITIZER) |
+#include <sanitizer/tsan_interface_atomic.h> |
+#endif |
+ |
namespace WTF { |
#if COMPILER(MSVC) |
@@ -98,6 +103,59 @@ ALWAYS_INLINE void atomicSetOneToZero(int volatile* ptr) |
ASSERT(*ptr == 1); |
__sync_lock_release(ptr); |
} |
+#endif |
+ |
+#if defined(THREAD_SANITIZER) |
+ALWAYS_INLINE void releaseStore(volatile int* ptr, int value) |
+{ |
+ __tsan_atomic32_store(ptr, value, __tsan_memory_order_release); |
+} |
+ |
+ALWAYS_INLINE int acquireLoad(volatile const int* ptr) |
+{ |
+ return __tsan_atomic32_load(ptr, __tsan_memory_order_acquire); |
+} |
+#else |
+ |
+#if CPU(X86) || CPU(X86_64) |
+// Only compiler barrier is needed. |
+#if COMPILER(MSVC) |
+// Starting from Visual Studio 2005 compiler guarantees acquire and release |
+// semantics for operations on volatile variables. See MSDN entry for |
+// MemoryBarrier macro. |
+#define MEMORY_BARRIER() |
+#else |
+#define MEMORY_BARRIER() __asm__ __volatile__("" : : : "memory") |
+#endif |
+#elif OS(LINUX) || OS(ANDROID) |
Alexander Potapenko
2014/03/17 08:02:28
Here you implicitly assume CPU(ARM). This may brea
Vyacheslav Egorov (Chromium)
2014/03/17 12:00:41
The comment assumes ARM indeed but the code itself
Alexander Potapenko
2014/03/17 12:09:58
Not sure how this can work on Android MIPS (or any
Vyacheslav Egorov (Chromium)
2014/03/17 12:16:07
I misread the docs (https://www.kernel.org/doc/Doc
|
+// On ARM __sync_synchronize generates dmb which is very expensive on single |
+// core devices which don't actually need it. Avoid the cost by calling into |
+// kuser_memory_barrier helper. |
+inline void memoryBarrier() |
+{ |
+ // Note: This is a function call, which is also an implicit compiler barrier. |
Alexander Potapenko
2014/03/17 08:02:28
If the 80-column limit applies here, please fix.
Vyacheslav Egorov (Chromium)
2014/03/17 12:00:41
(Fortunately) Blink does not have 80-column limit
|
+ typedef void (*KernelMemoryBarrierFunc)(); |
+ ((KernelMemoryBarrierFunc)0xffff0fa0)(); |
+} |
+#define MEMORY_BARRIER() memoryBarrier() |
+#else |
+#define MEMORY_BARRIER() __sync_synchronize() |
+#endif |
+ |
+ALWAYS_INLINE void releaseStore(volatile int* ptr, int value) |
+{ |
+ MEMORY_BARRIER(); |
+ *ptr = value; |
+} |
+ |
+ALWAYS_INLINE int acquireLoad(volatile const int* ptr) |
+{ |
+ int value = *ptr; |
+ MEMORY_BARRIER(); |
+ return value; |
+} |
+ |
+#undef MEMORY_BARRIER |
#endif |
@@ -109,5 +167,7 @@ using WTF::atomicDecrement; |
using WTF::atomicIncrement; |
using WTF::atomicTestAndSetToOne; |
using WTF::atomicSetOneToZero; |
+using WTF::acquireLoad; |
+using WTF::releaseStore; |
#endif // Atomics_h |