ManagedStatic.h revision 94fefe27f574ed98ad2522f8a7d1515e698ff036
1771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner//===-- llvm/Support/ManagedStatic.h - Static Global wrapper ----*- C++ -*-===// 2771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner// 3771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner// The LLVM Compiler Infrastructure 4771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner// 57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source 67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// License. See LICENSE.TXT for details. 7771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner// 8771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner//===----------------------------------------------------------------------===// 9771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner// 10771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner// This file defines the ManagedStatic class and the llvm_shutdown() function. 11771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner// 12771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner//===----------------------------------------------------------------------===// 13771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner 14771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner#ifndef LLVM_SUPPORT_MANAGED_STATIC_H 15771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner#define LLVM_SUPPORT_MANAGED_STATIC_H 16771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner 17b4d97b78dfd0d14a788fa3cb876f67a9e666b99bOwen Anderson#include "llvm/System/Atomic.h" 18e3cd5ca7e79f4359e8a101c211fc9c117eb62347Owen Anderson#include "llvm/System/Threading.h" 19b4d97b78dfd0d14a788fa3cb876f67a9e666b99bOwen Anderson 20771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattnernamespace llvm { 21771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner 22b4d97b78dfd0d14a788fa3cb876f67a9e666b99bOwen Anderson/// object_creator - Helper method for ManagedStatic. 23b4d97b78dfd0d14a788fa3cb876f67a9e666b99bOwen Andersontemplate<class C> 24b4d97b78dfd0d14a788fa3cb876f67a9e666b99bOwen Andersonvoid* object_creator() { 25b4d97b78dfd0d14a788fa3cb876f67a9e666b99bOwen Anderson return new C(); 26b4d97b78dfd0d14a788fa3cb876f67a9e666b99bOwen Anderson} 27b4d97b78dfd0d14a788fa3cb876f67a9e666b99bOwen Anderson 28771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner/// object_deleter - Helper method for ManagedStatic. 29771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner/// 30771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattnertemplate<class C> 31771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattnervoid object_deleter(void *Ptr) { 32771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner delete (C*)Ptr; 33771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner} 34771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner 35771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner/// ManagedStaticBase - Common base class for ManagedStatic instances. 36771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattnerclass ManagedStaticBase { 37771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattnerprotected: 38771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner // This should only be used as a static variable, which guarantees that this 39771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner // will be zero initialized. 40771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner mutable void *Ptr; 41771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner mutable void (*DeleterFn)(void*); 42771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner mutable const ManagedStaticBase *Next; 43fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 44b4d97b78dfd0d14a788fa3cb876f67a9e666b99bOwen Anderson void RegisterManagedStatic(void *(*creator)(), void (*deleter)(void*)) const; 45771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattnerpublic: 46fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman /// isConstructed - Return true if this object has not been created yet. 4768ce9ba666a7eb8c7eb3fb7888e4418fffd2e716Chris Lattner bool isConstructed() const { return Ptr != 0; } 48fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 49771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner void destroy() const; 50771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner}; 51771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner 52771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner/// ManagedStatic - This transparently changes the behavior of global statics to 53771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner/// be lazily constructed on demand (good for reducing startup times of dynamic 54771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner/// libraries that link in LLVM components) and for making destruction be 55771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner/// explicit through the llvm_shutdown() function call. 56771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner/// 57771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattnertemplate<class C> 58771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattnerclass ManagedStatic : public ManagedStaticBase { 59ca37b511fa1e542c936402c0023455fd9a444e76Owen Andersonpublic: 60ca37b511fa1e542c936402c0023455fd9a444e76Owen Anderson 61ca37b511fa1e542c936402c0023455fd9a444e76Owen Anderson // Accessors. 62ca37b511fa1e542c936402c0023455fd9a444e76Owen Anderson C &operator*() { 63b4d97b78dfd0d14a788fa3cb876f67a9e666b99bOwen Anderson void* tmp = Ptr; 6494fefe27f574ed98ad2522f8a7d1515e698ff036Owen Anderson if (llvm_is_multithreaded()) sys::MemoryFence(); 65b4d97b78dfd0d14a788fa3cb876f67a9e666b99bOwen Anderson if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>); 66b4d97b78dfd0d14a788fa3cb876f67a9e666b99bOwen Anderson 67771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner return *static_cast<C*>(Ptr); 68771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner } 69771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner C *operator->() { 70b4d97b78dfd0d14a788fa3cb876f67a9e666b99bOwen Anderson void* tmp = Ptr; 7194fefe27f574ed98ad2522f8a7d1515e698ff036Owen Anderson if (llvm_is_multithreaded()) sys::MemoryFence(); 72b4d97b78dfd0d14a788fa3cb876f67a9e666b99bOwen Anderson if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>); 73b4d97b78dfd0d14a788fa3cb876f67a9e666b99bOwen Anderson 74771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner return static_cast<C*>(Ptr); 75771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner } 76771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner const C &operator*() const { 77b4d97b78dfd0d14a788fa3cb876f67a9e666b99bOwen Anderson void* tmp = Ptr; 7894fefe27f574ed98ad2522f8a7d1515e698ff036Owen Anderson if (llvm_is_multithreaded()) sys::MemoryFence(); 79b4d97b78dfd0d14a788fa3cb876f67a9e666b99bOwen Anderson if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>); 80b4d97b78dfd0d14a788fa3cb876f67a9e666b99bOwen Anderson 81771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner return *static_cast<C*>(Ptr); 82771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner } 83771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner const C *operator->() const { 84b4d97b78dfd0d14a788fa3cb876f67a9e666b99bOwen Anderson void* tmp = Ptr; 8594fefe27f574ed98ad2522f8a7d1515e698ff036Owen Anderson if (llvm_is_multithreaded()) sys::MemoryFence(); 86b4d97b78dfd0d14a788fa3cb876f67a9e666b99bOwen Anderson if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>); 87fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 88b4d97b78dfd0d14a788fa3cb876f67a9e666b99bOwen Anderson return static_cast<C*>(Ptr); 89771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner } 90771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner}; 91771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner 92b4d7e35dde3ccbe0dc10bf13332ade9812586dd0Chris Lattnertemplate<void (*CleanupFn)(void*)> 93b4d7e35dde3ccbe0dc10bf13332ade9812586dd0Chris Lattnerclass ManagedCleanup : public ManagedStaticBase { 94b4d7e35dde3ccbe0dc10bf13332ade9812586dd0Chris Lattnerpublic: 95b4d7e35dde3ccbe0dc10bf13332ade9812586dd0Chris Lattner void Register() { RegisterManagedStatic(0, CleanupFn); } 96b4d7e35dde3ccbe0dc10bf13332ade9812586dd0Chris Lattner}; 97b4d7e35dde3ccbe0dc10bf13332ade9812586dd0Chris Lattner 98771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables. 99771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattnervoid llvm_shutdown(); 100771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner 101fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 102bdbf5fd1c9cfa30a348596b127394fa1f4caf033Chris Lattner/// llvm_shutdown_obj - This is a simple helper class that calls 103bdbf5fd1c9cfa30a348596b127394fa1f4caf033Chris Lattner/// llvm_shutdown() when it is destroyed. 104bdbf5fd1c9cfa30a348596b127394fa1f4caf033Chris Lattnerstruct llvm_shutdown_obj { 105b4d97b78dfd0d14a788fa3cb876f67a9e666b99bOwen Anderson llvm_shutdown_obj() { } 106b4d97b78dfd0d14a788fa3cb876f67a9e666b99bOwen Anderson explicit llvm_shutdown_obj(bool multithreaded) { 107b4d97b78dfd0d14a788fa3cb876f67a9e666b99bOwen Anderson if (multithreaded) llvm_start_multithreaded(); 108b4d97b78dfd0d14a788fa3cb876f67a9e666b99bOwen Anderson } 109bdbf5fd1c9cfa30a348596b127394fa1f4caf033Chris Lattner ~llvm_shutdown_obj() { llvm_shutdown(); } 110bdbf5fd1c9cfa30a348596b127394fa1f4caf033Chris Lattner}; 111fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 112771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner} 113771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner 114771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner#endif 115