Line data Source code
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 <atomic>
18 : #include <cstddef>
19 :
20 : namespace llvm {
21 :
22 : /// object_creator - Helper method for ManagedStatic.
23 : template <class C> struct object_creator {
24 1334430 : static void *call() { return new C(); }
25 : };
26 :
27 : /// object_deleter - Helper method for ManagedStatic.
28 : ///
29 : template <typename T> struct object_deleter {
30 1608380 : static void call(void *Ptr) { delete (T *)Ptr; }
31 : };
32 : template <typename T, size_t N> struct object_deleter<T[N]> {
33 : static void call(void *Ptr) { delete[](T *)Ptr; }
34 : };
35 :
36 : /// ManagedStaticBase - Common base class for ManagedStatic instances.
37 : class ManagedStaticBase {
38 : protected:
39 : // This should only be used as a static variable, which guarantees that this
40 : // will be zero initialized.
41 : mutable std::atomic<void *> Ptr;
42 : mutable void (*DeleterFn)(void*);
43 : mutable const ManagedStaticBase *Next;
44 :
45 : void RegisterManagedStatic(void *(*creator)(), void (*deleter)(void*)) const;
46 :
47 : public:
48 : /// isConstructed - Return true if this object has not been created yet.
49 2 : bool isConstructed() const { return Ptr != nullptr; }
50 :
51 : void destroy() const;
52 : };
53 :
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.
58 : ///
59 : template <class C, class Creator = object_creator<C>,
60 : class Deleter = object_deleter<C>>
61 : class ManagedStatic : public ManagedStaticBase {
62 : public:
63 : // Accessors.
64 775774381 : C &operator*() {
65 : void *Tmp = Ptr.load(std::memory_order_acquire);
66 775774381 : if (!Tmp)
67 1349297 : RegisterManagedStatic(Creator::call, Deleter::call);
68 :
69 775774381 : return *static_cast<C *>(Ptr.load(std::memory_order_relaxed));
70 : }
71 363444177 :
72 262474 : C *operator->() { return &**this; }
73 363444177 :
74 210312 : const C &operator*() const {
75 : void *Tmp = Ptr.load(std::memory_order_acquire);
76 363444177 : if (!Tmp)
77 : RegisterManagedStatic(Creator::call, Deleter::call);
78 388412763 :
79 : return *static_cast<C *>(Ptr.load(std::memory_order_relaxed));
80 388412763 : }
81 413990 :
82 : const C *operator->() const { return &**this; }
83 388412763 : };
84 :
85 136756 : /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
86 226981750 : void llvm_shutdown();
87 136756 :
88 17665 : /// llvm_shutdown_obj - This is a simple helper class that calls
89 : /// llvm_shutdown() when it is destroyed.
90 136756 : struct llvm_shutdown_obj {
91 : llvm_shutdown_obj() = default;
92 114990 : ~llvm_shutdown_obj() { llvm_shutdown(); }
93 136774372 : };
94 114622 :
95 114181 : } // end namespace llvm
96 :
97 114622 : #endif // LLVM_SUPPORT_MANAGEDSTATIC_H
|