1285SN/A//===-- llvm/Support/ManagedStatic.h - Static Global wrapper ----*- C++ -*-===// 2461SN/A// 3285SN/A// The LLVM Compiler Infrastructure 4285SN/A// 5285SN/A// This file is distributed under the University of Illinois Open Source 6285SN/A// License. See LICENSE.TXT for details. 7285SN/A// 8285SN/A//===----------------------------------------------------------------------===// 9285SN/A// 10285SN/A// This file defines the ManagedStatic class and the llvm_shutdown() function. 11285SN/A// 12285SN/A//===----------------------------------------------------------------------===// 13285SN/A 14285SN/A#ifndef LLVM_SUPPORT_MANAGED_STATIC_H 15285SN/A#define LLVM_SUPPORT_MANAGED_STATIC_H 16285SN/A 17285SN/A#include "llvm/Support/Atomic.h" 18285SN/A#include "llvm/Support/Threading.h" 19285SN/A#include "llvm/Support/Valgrind.h" 20285SN/A 21285SN/Anamespace llvm { 22285SN/A 23285SN/A/// object_creator - Helper method for ManagedStatic. 24285SN/Atemplate<class C> 25285SN/Avoid* object_creator() { 26285SN/A return new C(); 27285SN/A} 28285SN/A 29285SN/A/// object_deleter - Helper method for ManagedStatic. 30285SN/A/// 31285SN/Atemplate<typename T> struct object_deleter { 32285SN/A static void call(void * Ptr) { delete (T*)Ptr; } 33285SN/A}; 34285SN/Atemplate<typename T, size_t N> struct object_deleter<T[N]> { 35285SN/A static void call(void * Ptr) { delete[] (T*)Ptr; } 36285SN/A}; 37285SN/A 38285SN/A/// ManagedStaticBase - Common base class for ManagedStatic instances. 39285SN/Aclass ManagedStaticBase { 40285SN/Aprotected: 41285SN/A // This should only be used as a static variable, which guarantees that this 42285SN/A // will be zero initialized. 43285SN/A mutable void *Ptr; 44285SN/A mutable void (*DeleterFn)(void*); 45285SN/A mutable const ManagedStaticBase *Next; 46285SN/A 47285SN/A void RegisterManagedStatic(void *(*creator)(), void (*deleter)(void*)) const; 48285SN/Apublic: 49285SN/A /// isConstructed - Return true if this object has not been created yet. 50285SN/A bool isConstructed() const { return Ptr != 0; } 51285SN/A 52285SN/A void destroy() const; 53285SN/A}; 54285SN/A 55285SN/A/// ManagedStatic - This transparently changes the behavior of global statics to 56285SN/A/// be lazily constructed on demand (good for reducing startup times of dynamic 57285SN/A/// libraries that link in LLVM components) and for making destruction be 58285SN/A/// explicit through the llvm_shutdown() function call. 59285SN/A/// 60285SN/Atemplate<class C> 61285SN/Aclass ManagedStatic : public ManagedStaticBase { 62285SN/Apublic: 63285SN/A 64285SN/A // Accessors. 65285SN/A C &operator*() { 66285SN/A void* tmp = Ptr; 67285SN/A if (llvm_is_multithreaded()) sys::MemoryFence(); 68285SN/A if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); 69285SN/A TsanHappensAfter(this); 70285SN/A 71285SN/A return *static_cast<C*>(Ptr); 72285SN/A } 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. 100void llvm_shutdown(); 101 102/// llvm_shutdown_obj - This is a simple helper class that calls 103/// llvm_shutdown() when it is destroyed. 104struct llvm_shutdown_obj { 105 llvm_shutdown_obj() { } 106 explicit llvm_shutdown_obj(bool multithreaded) { 107 if (multithreaded) llvm_start_multithreaded(); 108 } 109 ~llvm_shutdown_obj() { llvm_shutdown(); } 110}; 111 112} 113 114#endif 115