diff options
-rw-r--r-- | include/llvm/Support/ManagedStatic.h | 44 | ||||
-rw-r--r-- | lib/Support/ManagedStatic.cpp | 53 |
2 files changed, 78 insertions, 19 deletions
diff --git a/include/llvm/Support/ManagedStatic.h b/include/llvm/Support/ManagedStatic.h index d0298e495d..7eecce3241 100644 --- a/include/llvm/Support/ManagedStatic.h +++ b/include/llvm/Support/ManagedStatic.h @@ -14,8 +14,16 @@ #ifndef LLVM_SUPPORT_MANAGED_STATIC_H #define LLVM_SUPPORT_MANAGED_STATIC_H +#include "llvm/System/Atomic.h" + namespace llvm { +/// object_creator - Helper method for ManagedStatic. +template<class C> +void* object_creator() { + return new C(); +} + /// object_deleter - Helper method for ManagedStatic. /// template<class C> @@ -32,7 +40,7 @@ protected: mutable void (*DeleterFn)(void*); mutable const ManagedStaticBase *Next; - void RegisterManagedStatic(void *ObjPtr, void (*deleter)(void*)) const; + void RegisterManagedStatic(void *(*creator)(), void (*deleter)(void*)) const; public: /// isConstructed - Return true if this object has not been created yet. bool isConstructed() const { return Ptr != 0; } @@ -51,25 +59,32 @@ public: // Accessors. C &operator*() { - if (!Ptr) LazyInit(); + void* tmp = Ptr; + sys::MemoryFence(); + if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>); + return *static_cast<C*>(Ptr); } C *operator->() { - if (!Ptr) LazyInit(); + void* tmp = Ptr; + sys::MemoryFence(); + if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>); + return static_cast<C*>(Ptr); } const C &operator*() const { - if (!Ptr) LazyInit(); + void* tmp = Ptr; + sys::MemoryFence(); + if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>); + return *static_cast<C*>(Ptr); } const C *operator->() const { - if (!Ptr) LazyInit(); - return static_cast<C*>(Ptr); - } + void* tmp = Ptr; + sys::MemoryFence(); + if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>); -public: - void LazyInit() const { - RegisterManagedStatic(new C(), object_deleter<C>); + return static_cast<C*>(Ptr); } }; @@ -80,6 +95,10 @@ public: }; +/// llvm_start_multithreaded - Allocate and initialize structures needed to +/// make LLVM safe for multithreading. +void llvm_start_multithreaded(); + /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables. void llvm_shutdown(); @@ -87,7 +106,10 @@ void llvm_shutdown(); /// llvm_shutdown_obj - This is a simple helper class that calls /// llvm_shutdown() when it is destroyed. struct llvm_shutdown_obj { - llvm_shutdown_obj() {} + llvm_shutdown_obj() { } + explicit llvm_shutdown_obj(bool multithreaded) { + if (multithreaded) llvm_start_multithreaded(); + } ~llvm_shutdown_obj() { llvm_shutdown(); } }; diff --git a/lib/Support/ManagedStatic.cpp b/lib/Support/ManagedStatic.cpp index c365e013c6..056b6c06c1 100644 --- a/lib/Support/ManagedStatic.cpp +++ b/lib/Support/ManagedStatic.cpp @@ -12,21 +12,44 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/ManagedStatic.h" +#include "llvm/Config/config.h" +#include "llvm/System/Atomic.h" +#include "llvm/System/Mutex.h" #include <cassert> using namespace llvm; static const ManagedStaticBase *StaticList = 0; -void ManagedStaticBase::RegisterManagedStatic(void *ObjPtr, +static sys::Mutex* ManagedStaticMutex = 0; + +void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(), void (*Deleter)(void*)) const { - assert(Ptr == 0 && DeleterFn == 0 && Next == 0 && - "Partially init static?"); - Ptr = ObjPtr; - DeleterFn = Deleter; + if (ManagedStaticMutex) { + ManagedStaticMutex->acquire(); + + if (Ptr == 0) { + void* tmp = Creator ? Creator() : 0; + + sys::MemoryFence(); + Ptr = tmp; + DeleterFn = Deleter; + + // Add to list of managed statics. + Next = StaticList; + StaticList = this; + } + + ManagedStaticMutex->release(); + } else { + assert(Ptr == 0 && DeleterFn == 0 && Next == 0 && + "Partially initialized ManagedStatic!?"); + Ptr = Creator ? Creator() : 0; + DeleterFn = Deleter; - // Add to list of managed statics. - Next = StaticList; - StaticList = this; + // Add to list of managed statics. + Next = StaticList; + StaticList = this; + } } void ManagedStaticBase::destroy() const { @@ -45,9 +68,23 @@ void ManagedStaticBase::destroy() const { DeleterFn = 0; } +void llvm::llvm_start_multithreaded() { +#if LLVM_MULTITHREADED + assert(ManagedStaticMutex == 0 && "Multithreaded LLVM already initialized!"); + ManagedStaticMutex = new sys::Mutex(true); +#else + assert(0 && "LLVM built without multithreading support!"); +#endif +} + /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables. void llvm::llvm_shutdown() { while (StaticList) StaticList->destroy(); + + if (ManagedStaticMutex) { + delete ManagedStaticMutex; + ManagedStaticMutex = 0; + } } |