Chromium Code Reviews| Index: Source/wtf/Atomics.h |
| diff --git a/Source/wtf/Atomics.h b/Source/wtf/Atomics.h |
| index 8ac6d9baade474c310446574612d1d27ef4a8bc3..82113f4abaa3ef8c16e71f8a4bfaefda56f44436 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,60 @@ 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 CPU(ARM) && (OS(LINUX) || OS(ANDROID)) |
| +// 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. |
| + typedef void (*KernelMemoryBarrierFunc)(); |
| + ((KernelMemoryBarrierFunc)0xffff0fa0)(); |
| +} |
| +#define MEMORY_BARRIER() memoryBarrier() |
| +#else |
| +// Fallback to the compiler intrinsic on all other platforms. |
| +#define MEMORY_BARRIER() __sync_synchronize() |
| +#endif |
| + |
| +ALWAYS_INLINE void releaseStore(volatile int* ptr, int value) |
| +{ |
| + MEMORY_BARRIER(); |
|
wibling-chromium
2014/03/20 08:05:31
I don't quite understand this. Wouldn't you normal
Dmitry Vyukov
2014/03/20 09:27:49
No
|
| + *ptr = value; |
| +} |
| + |
| +ALWAYS_INLINE int acquireLoad(volatile const int* ptr) |
| +{ |
| + int value = *ptr; |
| + MEMORY_BARRIER(); |
| + return value; |
| +} |
| + |
| +#undef MEMORY_BARRIER |
| #endif |
| @@ -109,5 +168,7 @@ using WTF::atomicDecrement; |
| using WTF::atomicIncrement; |
| using WTF::atomicTestAndSetToOne; |
| using WTF::atomicSetOneToZero; |
| +using WTF::acquireLoad; |
| +using WTF::releaseStore; |
| #endif // Atomics_h |