• 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/Compiler.h"
18 #include <atomic>
19 #include <cstddef>
20 
21 namespace llvm {
22 
23 /// object_creator - Helper method for ManagedStatic.
24 template<class C>
object_creator()25 LLVM_LIBRARY_VISIBILITY void* object_creator() {
26   return new C();
27 }
28 
29 /// object_deleter - Helper method for ManagedStatic.
30 ///
31 template <typename T> struct LLVM_LIBRARY_VISIBILITY object_deleter {
callobject_deleter32   static void call(void *Ptr) { delete (T *)Ptr; }
33 };
34 template <typename T, size_t N>
35 struct LLVM_LIBRARY_VISIBILITY object_deleter<T[N]> {
36   static void call(void *Ptr) { delete[](T *)Ptr; }
37 };
38 
39 /// ManagedStaticBase - Common base class for ManagedStatic instances.
40 class ManagedStaticBase {
41 protected:
42   // This should only be used as a static variable, which guarantees that this
43   // will be zero initialized.
44   mutable std::atomic<void *> Ptr;
45   mutable void (*DeleterFn)(void*);
46   mutable const ManagedStaticBase *Next;
47 
48   void RegisterManagedStatic(void *(*creator)(), void (*deleter)(void*)) const;
49 
50 public:
51   /// isConstructed - Return true if this object has not been created yet.
52   bool isConstructed() const { return Ptr != nullptr; }
53 
54   void destroy() const;
55 };
56 
57 /// ManagedStatic - This transparently changes the behavior of global statics to
58 /// be lazily constructed on demand (good for reducing startup times of dynamic
59 /// libraries that link in LLVM components) and for making destruction be
60 /// explicit through the llvm_shutdown() function call.
61 ///
62 template<class C>
63 class ManagedStatic : public ManagedStaticBase {
64 public:
65   // Accessors.
66   C &operator*() {
67     void *Tmp = Ptr.load(std::memory_order_acquire);
68     if (!Tmp)
69       RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
70 
71     return *static_cast<C *>(Ptr.load(std::memory_order_relaxed));
72   }
73 
74   C *operator->() { return &**this; }
75 
76   const C &operator*() const {
77     void *Tmp = Ptr.load(std::memory_order_acquire);
78     if (!Tmp)
79       RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
80 
81     return *static_cast<C *>(Ptr.load(std::memory_order_relaxed));
82   }
83 
84   const C *operator->() const { return &**this; }
85 };
86 
87 /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
88 void llvm_shutdown();
89 
90 /// llvm_shutdown_obj - This is a simple helper class that calls
91 /// llvm_shutdown() when it is destroyed.
92 struct llvm_shutdown_obj {
93   llvm_shutdown_obj() = default;
94   ~llvm_shutdown_obj() { llvm_shutdown(); }
95 };
96 
97 } // end namespace llvm
98 
99 #endif // LLVM_SUPPORT_MANAGEDSTATIC_H
100