Chromium Code Reviews| 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 |