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