1181053Srwatson//===-- llvm/Support/ManagedStatic.h - Static Global wrapper ----*- C++ -*-===// 2180701Srwatson// 3170407Srwatson// The LLVM Compiler Infrastructure 4155192Srwatson// 5155192Srwatson// This file is distributed under the University of Illinois Open Source 6155192Srwatson// License. See LICENSE.TXT for details. 7155192Srwatson// 8155192Srwatson//===----------------------------------------------------------------------===// 9155192Srwatson// 10155192Srwatson// This file defines the ManagedStatic class and the llvm_shutdown() function. 11155192Srwatson// 12155192Srwatson//===----------------------------------------------------------------------===// 13155192Srwatson 14180701Srwatson#ifndef LLVM_SUPPORT_MANAGED_STATIC_H 15155192Srwatson#define LLVM_SUPPORT_MANAGED_STATIC_H 16155192Srwatson 17155192Srwatson#include "llvm/Support/Atomic.h" 18155192Srwatson#include "llvm/Support/Threading.h" 19155192Srwatson#include "llvm/Support/Valgrind.h" 20155192Srwatson 21155192Srwatsonnamespace llvm { 22155192Srwatson 23155192Srwatson/// object_creator - Helper method for ManagedStatic. 24155192Srwatsontemplate<class C> 25155192Srwatsonvoid* object_creator() { 26155192Srwatson return new C(); 27155192Srwatson} 28155192Srwatson 29155192Srwatson/// object_deleter - Helper method for ManagedStatic. 30155192Srwatson/// 31178186Srwatsontemplate<typename T> struct object_deleter { 32178186Srwatson static void call(void * Ptr) { delete (T*)Ptr; } 33178186Srwatson}; 34155192Srwatsontemplate<typename T, size_t N> struct object_deleter<T[N]> { 35155192Srwatson static void call(void * Ptr) { delete[] (T*)Ptr; } 36155192Srwatson}; 37155192Srwatson 38155192Srwatson/// ManagedStaticBase - Common base class for ManagedStatic instances. 39155192Srwatsonclass ManagedStaticBase { 40155192Srwatsonprotected: 41155192Srwatson // This should only be used as a static variable, which guarantees that this 42155192Srwatson // will be zero initialized. 43155192Srwatson mutable void *Ptr; 44155192Srwatson mutable void (*DeleterFn)(void*); 45155192Srwatson mutable const ManagedStaticBase *Next; 46164033Srwatson 47155192Srwatson void RegisterManagedStatic(void *(*creator)(), void (*deleter)(void*)) const; 48155192Srwatsonpublic: 49155192Srwatson /// isConstructed - Return true if this object has not been created yet. 50155192Srwatson bool isConstructed() const { return Ptr != 0; } 51155192Srwatson 52155192Srwatson void destroy() const; 53171144Srwatson}; 54155192Srwatson 55155192Srwatson/// ManagedStatic - This transparently changes the behavior of global statics to 56155192Srwatson/// be lazily constructed on demand (good for reducing startup times of dynamic 57155192Srwatson/// libraries that link in LLVM components) and for making destruction be 58155192Srwatson/// explicit through the llvm_shutdown() function call. 59155192Srwatson/// 60155192Srwatsontemplate<class C> 61155192Srwatsonclass ManagedStatic : public ManagedStaticBase { 62155192Srwatsonpublic: 63155406Srwatson 64156291Srwatson // Accessors. 65155406Srwatson C &operator*() { 66155406Srwatson void* tmp = Ptr; 67155192Srwatson if (llvm_is_multithreaded()) sys::MemoryFence(); 68155192Srwatson if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); 69155192Srwatson TsanHappensAfter(this); 70155192Srwatson 71155192Srwatson return *static_cast<C*>(Ptr); 72155192Srwatson } 73155406Srwatson C *operator->() { 74155406Srwatson void* tmp = Ptr; 75156888Srwatson if (llvm_is_multithreaded()) sys::MemoryFence(); 76170407Srwatson if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); 77155192Srwatson TsanHappensAfter(this); 78155192Srwatson 79155192Srwatson return static_cast<C*>(Ptr); 80155192Srwatson } 81171144Srwatson const C &operator*() const { 82171144Srwatson void* tmp = Ptr; 83171144Srwatson if (llvm_is_multithreaded()) sys::MemoryFence(); 84155192Srwatson if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); 85170196Srwatson TsanHappensAfter(this); 86170196Srwatson 87170196Srwatson return *static_cast<C*>(Ptr); 88155192Srwatson } 89155192Srwatson const C *operator->() const { 90156889Srwatson void* tmp = Ptr; 91156889Srwatson if (llvm_is_multithreaded()) sys::MemoryFence(); 92155192Srwatson if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); 93155192Srwatson TsanHappensAfter(this); 94162176Srwatson 95162176Srwatson return static_cast<C*>(Ptr); 96155192Srwatson } 97156889Srwatson}; 98156889Srwatson 99161813Swsalamon/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables. 100161813Swsalamonvoid llvm_shutdown(); 101155192Srwatson 102155192Srwatson/// llvm_shutdown_obj - This is a simple helper class that calls 103155192Srwatson/// llvm_shutdown() when it is destroyed. 104155192Srwatsonstruct llvm_shutdown_obj { 105156889Srwatson llvm_shutdown_obj() { } 106155192Srwatson explicit llvm_shutdown_obj(bool multithreaded) { 107155192Srwatson if (multithreaded) llvm_start_multithreaded(); 108170691Srwatson } 109155192Srwatson ~llvm_shutdown_obj() { llvm_shutdown(); } 110156889Srwatson}; 111155192Srwatson 112155192Srwatson} 113155192Srwatson 114155192Srwatson#endif 115156889Srwatson