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_MANAGEDSTATIC_H 15 #define LLVM_SUPPORT_MANAGEDSTATIC_H 16 17 #include <atomic> 18 #include <cstddef> 19 20 namespace llvm { 21 22 /// object_creator - Helper method for ManagedStatic. 23 template <class C> struct object_creator { 24 static void *call() { return new C(); } 25 }; 26 27 /// object_deleter - Helper method for ManagedStatic. 28 /// 29 template <typename T> struct object_deleter { 30 static void call(void *Ptr) { delete (T *)Ptr; } 31 }; 32 template <typename T, size_t N> struct object_deleter<T[N]> { 33 static void call(void *Ptr) { delete[](T *)Ptr; } 34 }; 35 36 /// ManagedStaticBase - Common base class for ManagedStatic instances. 37 class ManagedStaticBase { 38 protected: 39 // This should only be used as a static variable, which guarantees that this 40 // will be zero initialized. 41 mutable std::atomic<void *> Ptr; 42 mutable void (*DeleterFn)(void*); 43 mutable const ManagedStaticBase *Next; 44 45 void RegisterManagedStatic(void *(*creator)(), void (*deleter)(void*)) const; 46 47 public: 48 /// isConstructed - Return true if this object has not been created yet. 49 bool isConstructed() const { return Ptr != nullptr; } 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, class Creator = object_creator<C>, 60 class Deleter = object_deleter<C>> 61 class ManagedStatic : public ManagedStaticBase { 62 public: 63 // Accessors. 64 C &operator*() { 65 void *Tmp = Ptr.load(std::memory_order_acquire); 66 if (!Tmp) 67 RegisterManagedStatic(Creator::call, Deleter::call); 68 69 return *static_cast<C *>(Ptr.load(std::memory_order_relaxed)); 70 } 71 72 C *operator->() { return &**this; } 73 74 const C &operator*() const { 75 void *Tmp = Ptr.load(std::memory_order_acquire); 76 if (!Tmp) 77 RegisterManagedStatic(Creator::call, Deleter::call); 78 79 return *static_cast<C *>(Ptr.load(std::memory_order_relaxed)); 80 } 81 82 const C *operator->() const { return &**this; } 83 }; 84 85 /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables. 86 void llvm_shutdown(); 87 88 /// llvm_shutdown_obj - This is a simple helper class that calls 89 /// llvm_shutdown() when it is destroyed. 90 struct llvm_shutdown_obj { 91 llvm_shutdown_obj() = default; 92 ~llvm_shutdown_obj() { llvm_shutdown(); } 93 }; 94 95 } // end namespace llvm 96 97 #endif // LLVM_SUPPORT_MANAGEDSTATIC_H 98