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/Support/Atomic.h"
18 #include "llvm/Support/Threading.h"
19 #include "llvm/Support/Valgrind.h"
23 /// object_creator - Helper method for ManagedStatic.
25 void* object_creator() {
29 /// object_deleter - Helper method for ManagedStatic.
31 template<typename T> struct object_deleter {
32 static void call(void * Ptr) { delete (T*)Ptr; }
34 template<typename T, size_t N> struct object_deleter<T[N]> {
35 static void call(void * Ptr) { delete[] (T*)Ptr; }
38 /// ManagedStaticBase - Common base class for ManagedStatic instances.
39 class ManagedStaticBase {
41 // This should only be used as a static variable, which guarantees that this
42 // will be zero initialized.
44 mutable void (*DeleterFn)(void*);
45 mutable const ManagedStaticBase *Next;
47 void RegisterManagedStatic(void *(*creator)(), void (*deleter)(void*)) const;
49 /// isConstructed - Return true if this object has not been created yet.
50 bool isConstructed() const { return Ptr != nullptr; }
55 /// ManagedStatic - This transparently changes the behavior of global statics to
56 /// be lazily constructed on demand (good for reducing startup times of dynamic
57 /// libraries that link in LLVM components) and for making destruction be
58 /// explicit through the llvm_shutdown() function call.
61 class ManagedStatic : public ManagedStaticBase {
67 if (llvm_is_multithreaded()) sys::MemoryFence();
68 if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
69 TsanHappensAfter(this);
71 return *static_cast<C*>(Ptr);
75 if (llvm_is_multithreaded()) sys::MemoryFence();
76 if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
77 TsanHappensAfter(this);
79 return static_cast<C*>(Ptr);
81 const C &operator*() const {
83 if (llvm_is_multithreaded()) sys::MemoryFence();
84 if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
85 TsanHappensAfter(this);
87 return *static_cast<C*>(Ptr);
89 const C *operator->() const {
91 if (llvm_is_multithreaded()) sys::MemoryFence();
92 if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
93 TsanHappensAfter(this);
95 return static_cast<C*>(Ptr);
99 /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
100 void llvm_shutdown();
102 /// llvm_shutdown_obj - This is a simple helper class that calls
103 /// llvm_shutdown() when it is destroyed.
104 struct llvm_shutdown_obj {
105 llvm_shutdown_obj() { }
106 ~llvm_shutdown_obj() { llvm_shutdown(); }