diff options
-rw-r--r-- | llvm/include/llvm/Support/ManagedStatic.h | 42 | ||||
-rw-r--r-- | llvm/lib/Support/ManagedStatic.cpp | 15 |
2 files changed, 17 insertions, 40 deletions
diff --git a/llvm/include/llvm/Support/ManagedStatic.h b/llvm/include/llvm/Support/ManagedStatic.h index 3a34bdbd01f..ec8154b828e 100644 --- a/llvm/include/llvm/Support/ManagedStatic.h +++ b/llvm/include/llvm/Support/ManagedStatic.h @@ -14,9 +14,9 @@ #ifndef LLVM_SUPPORT_MANAGEDSTATIC_H #define LLVM_SUPPORT_MANAGEDSTATIC_H -#include "llvm/Support/Atomic.h" #include "llvm/Support/Compiler.h" -#include "llvm/Support/Threading.h" +#include <atomic> +#include <cstddef> namespace llvm { @@ -41,7 +41,7 @@ class ManagedStaticBase { protected: // This should only be used as a static variable, which guarantees that this // will be zero initialized. - mutable void *Ptr; + mutable std::atomic<void *> Ptr; mutable void (*DeleterFn)(void*); mutable const ManagedStaticBase *Next; @@ -61,40 +61,26 @@ public: template<class C> class ManagedStatic : public ManagedStaticBase { public: - // Accessors. C &operator*() { - void* tmp = Ptr; - if (llvm_is_multithreaded()) sys::MemoryFence(); - if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); - TsanHappensAfter(this); + void *Tmp = Ptr.load(std::memory_order_acquire); + if (!Tmp) + RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); - return *static_cast<C*>(Ptr); + return *static_cast<C *>(Ptr.load(std::memory_order_relaxed)); } - C *operator->() { - void* tmp = Ptr; - if (llvm_is_multithreaded()) sys::MemoryFence(); - if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); - TsanHappensAfter(this); - return static_cast<C*>(Ptr); - } + C *operator->() { return &**this; } + const C &operator*() const { - void* tmp = Ptr; - if (llvm_is_multithreaded()) sys::MemoryFence(); - if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); - TsanHappensAfter(this); + void *Tmp = Ptr.load(std::memory_order_acquire); + if (!Tmp) + RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); - return *static_cast<C*>(Ptr); + return *static_cast<C *>(Ptr.load(std::memory_order_relaxed)); } - const C *operator->() const { - void* tmp = Ptr; - if (llvm_is_multithreaded()) sys::MemoryFence(); - if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); - TsanHappensAfter(this); - return static_cast<C*>(Ptr); - } + const C *operator->() const { return &**this; } }; /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables. diff --git a/llvm/lib/Support/ManagedStatic.cpp b/llvm/lib/Support/ManagedStatic.cpp index bc4fe954e22..7dd31315f90 100644 --- a/llvm/lib/Support/ManagedStatic.cpp +++ b/llvm/lib/Support/ManagedStatic.cpp @@ -13,7 +13,6 @@ #include "llvm/Support/ManagedStatic.h" #include "llvm/Config/config.h" -#include "llvm/Support/Atomic.h" #include "llvm/Support/Mutex.h" #include "llvm/Support/MutexGuard.h" #include "llvm/Support/Threading.h" @@ -42,18 +41,10 @@ void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(), if (llvm_is_multithreaded()) { MutexGuard Lock(*getManagedStaticMutex()); - if (!Ptr) { - void* tmp = Creator(); + if (!Ptr.load(std::memory_order_relaxed)) { + void *Tmp = Creator(); - TsanHappensBefore(this); - sys::MemoryFence(); - - // This write is racy against the first read in the ManagedStatic - // accessors. The race is benign because it does a second read after a - // memory fence, at which point it isn't possible to get a partial value. - TsanIgnoreWritesBegin(); - Ptr = tmp; - TsanIgnoreWritesEnd(); + Ptr.store(Tmp, std::memory_order_release); DeleterFn = Deleter; // Add to list of managed statics. |