• 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 public:
50   /// isConstructed - Return true if this object has not been created yet.
51   bool isConstructed() const { return Ptr != nullptr; }
52 
53   void destroy() const;
54 };
55 
56 /// ManagedStatic - This transparently changes the behavior of global statics to
57 /// be lazily constructed on demand (good for reducing startup times of dynamic
58 /// libraries that link in LLVM components) and for making destruction be
59 /// explicit through the llvm_shutdown() function call.
60 ///
61 template<class C>
62 class ManagedStatic : public ManagedStaticBase {
63 public:
64   // Accessors.
65   C &operator*() {
66     void *Tmp = Ptr.load(std::memory_order_acquire);
67     if (!Tmp)
68       RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
69 
70     return *static_cast<C *>(Ptr.load(std::memory_order_relaxed));
71   }
72 
73   C *operator->() { return &**this; }
74 
75   const C &operator*() const {
76     void *Tmp = Ptr.load(std::memory_order_acquire);
77     if (!Tmp)
78       RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
79 
80     return *static_cast<C *>(Ptr.load(std::memory_order_relaxed));
81   }
82 
83   const C *operator->() const { return &**this; }
84 };
85 
86 /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
87 void llvm_shutdown();
88 
89 /// llvm_shutdown_obj - This is a simple helper class that calls
90 /// llvm_shutdown() when it is destroyed.
91 struct llvm_shutdown_obj {
92   llvm_shutdown_obj() { }
93   ~llvm_shutdown_obj() { llvm_shutdown(); }
94 };
95 
96 }
97 
98 #endif
99