• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- llvm/Support/ManagedStatic.h - Static Global wrapper ----*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the ManagedStatic class and the llvm_shutdown() function.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_SUPPORT_MANAGEDSTATIC_H
15 #define LLVM_SUPPORT_MANAGEDSTATIC_H
16 
17 #include "llvm/Support/Atomic.h"
18 #include "llvm/Support/Compiler.h"
19 #include "llvm/Support/Threading.h"
20 
21 namespace llvm {
22 
23 /// object_creator - Helper method for ManagedStatic.
24 template<class C>
object_creator()25 void* object_creator() {
26   return new C();
27 }
28 
29 /// object_deleter - Helper method for ManagedStatic.
30 ///
31 template<typename T> struct object_deleter {
callobject_deleter32   static void call(void * Ptr) { delete (T*)Ptr; }
33 };
34 template<typename T, size_t N> struct object_deleter<T[N]> {
35   static void call(void * Ptr) { delete[] (T*)Ptr; }
36 };
37 
38 /// ManagedStaticBase - Common base class for ManagedStatic instances.
39 class ManagedStaticBase {
40 protected:
41   // This should only be used as a static variable, which guarantees that this
42   // will be zero initialized.
43   mutable void *Ptr;
44   mutable void (*DeleterFn)(void*);
45   mutable const ManagedStaticBase *Next;
46 
47   void RegisterManagedStatic(void *(*creator)(), void (*deleter)(void*)) const;
48 public:
49   /// isConstructed - Return true if this object has not been created yet.
50   bool isConstructed() const { return Ptr != nullptr; }
51 
52   void destroy() const;
53 };
54 
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.
59 ///
60 template<class C>
61 class ManagedStatic : public ManagedStaticBase {
62 public:
63 
64   // Accessors.
65   C &operator*() {
66     void* tmp = Ptr;
67     if (llvm_is_multithreaded()) sys::MemoryFence();
68     if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
69     TsanHappensAfter(this);
70 
71     return *static_cast<C*>(Ptr);
72   }
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.
100 void llvm_shutdown();
101 
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(); }
107 };
108 
109 }
110 
111 #endif
112