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