1 //===-- llvm/Support/ManagedStatic.h - Static Global wrapper ----*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the ManagedStatic class and the llvm_shutdown() function.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_SUPPORT_MANAGED_STATIC_H
15 #define LLVM_SUPPORT_MANAGED_STATIC_H
17 #include "llvm/System/Atomic.h"
18 #include "llvm/System/Threading.h"
22 /// object_creator - Helper method for ManagedStatic.
24 void* object_creator() {
28 /// object_deleter - Helper method for ManagedStatic.
30 template<typename T> struct object_deleter {
31 static void call(void * Ptr) { delete (T*)Ptr; }
33 template<typename T, size_t N> struct object_deleter<T[N]> {
34 static void call(void * Ptr) { delete[] (T*)Ptr; }
37 /// ManagedStaticBase - Common base class for ManagedStatic instances.
38 class ManagedStaticBase {
40 // This should only be used as a static variable, which guarantees that this
41 // will be zero initialized.
43 mutable void (*DeleterFn)(void*);
44 mutable const ManagedStaticBase *Next;
46 void RegisterManagedStatic(void *(*creator)(), void (*deleter)(void*)) const;
48 /// isConstructed - Return true if this object has not been created yet.
49 bool isConstructed() const { return Ptr != 0; }
54 /// ManagedStatic - This transparently changes the behavior of global statics to
55 /// be lazily constructed on demand (good for reducing startup times of dynamic
56 /// libraries that link in LLVM components) and for making destruction be
57 /// explicit through the llvm_shutdown() function call.
60 class ManagedStatic : public ManagedStaticBase {
66 if (llvm_is_multithreaded()) sys::MemoryFence();
67 if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
69 return *static_cast<C*>(Ptr);
73 if (llvm_is_multithreaded()) sys::MemoryFence();
74 if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
76 return static_cast<C*>(Ptr);
78 const C &operator*() const {
80 if (llvm_is_multithreaded()) sys::MemoryFence();
81 if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
83 return *static_cast<C*>(Ptr);
85 const C *operator->() const {
87 if (llvm_is_multithreaded()) sys::MemoryFence();
88 if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
90 return static_cast<C*>(Ptr);
94 template<void (*CleanupFn)(void*)>
95 class ManagedCleanup : public ManagedStaticBase {
97 void Register() { RegisterManagedStatic(0, CleanupFn); }
100 /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
101 void llvm_shutdown();
104 /// llvm_shutdown_obj - This is a simple helper class that calls
105 /// llvm_shutdown() when it is destroyed.
106 struct llvm_shutdown_obj {
107 llvm_shutdown_obj() { }
108 explicit llvm_shutdown_obj(bool multithreaded) {
109 if (multithreaded) llvm_start_multithreaded();
111 ~llvm_shutdown_obj() { llvm_shutdown(); }