diff options
Diffstat (limited to 'include/llvm/Support/ManagedStatic.h')
-rw-r--r-- | include/llvm/Support/ManagedStatic.h | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/include/llvm/Support/ManagedStatic.h b/include/llvm/Support/ManagedStatic.h new file mode 100644 index 0000000..619cc20 --- /dev/null +++ b/include/llvm/Support/ManagedStatic.h @@ -0,0 +1,120 @@ +//===-- llvm/Support/ManagedStatic.h - Static Global wrapper ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the ManagedStatic class and the llvm_shutdown() function. +// +//===----------------------------------------------------------------------===// + +#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> +void object_deleter(void *Ptr) { + delete (C*)Ptr; +} + +/// ManagedStaticBase - Common base class for ManagedStatic instances. +class ManagedStaticBase { +protected: + // This should only be used as a static variable, which guarantees that this + // will be zero initialized. + mutable void *Ptr; + mutable void (*DeleterFn)(void*); + mutable const ManagedStaticBase *Next; + + 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; } + + void destroy() const; +}; + +/// ManagedStatic - This transparently changes the behavior of global statics to +/// be lazily constructed on demand (good for reducing startup times of dynamic +/// libraries that link in LLVM components) and for making destruction be +/// explicit through the llvm_shutdown() function call. +/// +template<class C> +class ManagedStatic : public ManagedStaticBase { +public: + + // Accessors. + C &operator*() { + void* tmp = Ptr; + sys::MemoryFence(); + if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>); + + return *static_cast<C*>(Ptr); + } + C *operator->() { + void* tmp = Ptr; + sys::MemoryFence(); + if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>); + + return static_cast<C*>(Ptr); + } + const C &operator*() const { + void* tmp = Ptr; + sys::MemoryFence(); + if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>); + + return *static_cast<C*>(Ptr); + } + const C *operator->() const { + void* tmp = Ptr; + sys::MemoryFence(); + if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>); + + return static_cast<C*>(Ptr); + } +}; + +template<void (*CleanupFn)(void*)> +class ManagedCleanup : public ManagedStaticBase { +public: + void Register() { RegisterManagedStatic(0, CleanupFn); } +}; + + +/// llvm_start_multithreaded - Allocate and initialize structures needed to +/// make LLVM safe for multithreading. The return value indicates whether +/// multithreaded initialization succeeded. LLVM will still be operational +/// on "failed" return, but will not be safe to run multithreaded. +bool llvm_start_multithreaded(); + +/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables. +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() { } + explicit llvm_shutdown_obj(bool multithreaded) { + if (multithreaded) llvm_start_multithreaded(); + } + ~llvm_shutdown_obj() { llvm_shutdown(); } +}; + +} + +#endif |