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