1 //===-- llvm/Support/ManagedStatic.h - Static Global wrapper ----*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the ManagedStatic class and the llvm_shutdown() function. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_SUPPORT_MANAGED_STATIC_H 15 #define LLVM_SUPPORT_MANAGED_STATIC_H 16 17 #include "llvm/Support/Atomic.h" 18 #include "llvm/Support/Threading.h" 19 20 namespace llvm { 21 22 /// object_creator - Helper method for ManagedStatic. 23 template<class C> object_creator()24void* object_creator() { 25 return new C(); 26 } 27 28 /// object_deleter - Helper method for ManagedStatic. 29 /// 30 template<typename T> struct object_deleter { callobject_deleter31 static void call(void * Ptr) { delete (T*)Ptr; } 32 }; 33 template<typename T, size_t N> struct object_deleter<T[N]> { 34 static void call(void * Ptr) { delete[] (T*)Ptr; } 35 }; 36 37 /// ManagedStaticBase - Common base class for ManagedStatic instances. 38 class ManagedStaticBase { 39 protected: 40 // This should only be used as a static variable, which guarantees that this 41 // will be zero initialized. 42 mutable void *Ptr; 43 mutable void (*DeleterFn)(void*); 44 mutable const ManagedStaticBase *Next; 45 46 void RegisterManagedStatic(void *(*creator)(), void (*deleter)(void*)) const; 47 public: 48 /// isConstructed - Return true if this object has not been created yet. 49 bool isConstructed() const { return Ptr != 0; } 50 51 void destroy() const; 52 }; 53 54 /// ManagedStatic - This transparently changes the behavior of global statics to 55 /// be lazily constructed on demand (good for reducing startup times of dynamic 56 /// libraries that link in LLVM components) and for making destruction be 57 /// explicit through the llvm_shutdown() function call. 58 /// 59 template<class C> 60 class ManagedStatic : public ManagedStaticBase { 61 public: 62 63 // Accessors. 64 C &operator*() { 65 void* tmp = Ptr; 66 if (llvm_is_multithreaded()) sys::MemoryFence(); 67 if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); 68 69 return *static_cast<C*>(Ptr); 70 } 71 C *operator->() { 72 void* tmp = Ptr; 73 if (llvm_is_multithreaded()) sys::MemoryFence(); 74 if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); 75 76 return static_cast<C*>(Ptr); 77 } 78 const C &operator*() const { 79 void* tmp = Ptr; 80 if (llvm_is_multithreaded()) sys::MemoryFence(); 81 if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); 82 83 return *static_cast<C*>(Ptr); 84 } 85 const C *operator->() const { 86 void* tmp = Ptr; 87 if (llvm_is_multithreaded()) sys::MemoryFence(); 88 if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); 89 90 return static_cast<C*>(Ptr); 91 } 92 }; 93 94 /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables. 95 void llvm_shutdown(); 96 97 98 /// llvm_shutdown_obj - This is a simple helper class that calls 99 /// llvm_shutdown() when it is destroyed. 100 struct llvm_shutdown_obj { 101 llvm_shutdown_obj() { } 102 explicit llvm_shutdown_obj(bool multithreaded) { 103 if (multithreaded) llvm_start_multithreaded(); 104 } 105 ~llvm_shutdown_obj() { llvm_shutdown(); } 106 }; 107 108 } 109 110 #endif 111