Add llvm_start_multithreaded(), which starts up the LLVM internals in thread-safe...
[oota-llvm.git] / include / llvm / Support / ManagedStatic.h
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_MANAGED_STATIC_H
15 #define LLVM_SUPPORT_MANAGED_STATIC_H
16
17 #include "llvm/System/Atomic.h"
18
19 namespace llvm {
20
21 /// object_creator - Helper method for ManagedStatic.
22 template<class C>
23 void* object_creator() {
24   return new C();
25 }
26
27 /// object_deleter - Helper method for ManagedStatic.
28 ///
29 template<class C>
30 void object_deleter(void *Ptr) {
31   delete (C*)Ptr;
32 }
33
34 /// ManagedStaticBase - Common base class for ManagedStatic instances.
35 class ManagedStaticBase {
36 protected:
37   // This should only be used as a static variable, which guarantees that this
38   // will be zero initialized.
39   mutable void *Ptr;
40   mutable void (*DeleterFn)(void*);
41   mutable const ManagedStaticBase *Next;
42
43   void RegisterManagedStatic(void *(*creator)(), void (*deleter)(void*)) const;
44 public:
45   /// isConstructed - Return true if this object has not been created yet.
46   bool isConstructed() const { return Ptr != 0; }
47
48   void destroy() const;
49 };
50
51 /// ManagedStatic - This transparently changes the behavior of global statics to
52 /// be lazily constructed on demand (good for reducing startup times of dynamic
53 /// libraries that link in LLVM components) and for making destruction be
54 /// explicit through the llvm_shutdown() function call.
55 ///
56 template<class C>
57 class ManagedStatic : public ManagedStaticBase {
58 public:
59
60   // Accessors.
61   C &operator*() {
62     void* tmp = Ptr;
63     sys::MemoryFence();
64     if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>);
65
66     return *static_cast<C*>(Ptr);
67   }
68   C *operator->() {
69     void* tmp = Ptr;
70     sys::MemoryFence();
71     if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>);
72
73     return static_cast<C*>(Ptr);
74   }
75   const C &operator*() const {
76     void* tmp = Ptr;
77     sys::MemoryFence();
78     if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>);
79
80     return *static_cast<C*>(Ptr);
81   }
82   const C *operator->() const {
83     void* tmp = Ptr;
84     sys::MemoryFence();
85     if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>);
86
87     return static_cast<C*>(Ptr);
88   }
89 };
90
91 template<void (*CleanupFn)(void*)>
92 class ManagedCleanup : public ManagedStaticBase {
93 public:
94   void Register() { RegisterManagedStatic(0, CleanupFn); }
95 };
96
97
98 /// llvm_start_multithreaded - Allocate and initialize structures needed to
99 /// make LLVM safe for multithreading.
100 void llvm_start_multithreaded();
101
102 /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
103 void llvm_shutdown();
104
105
106 /// llvm_shutdown_obj - This is a simple helper class that calls
107 /// llvm_shutdown() when it is destroyed.
108 struct llvm_shutdown_obj {
109   llvm_shutdown_obj() { }
110   explicit llvm_shutdown_obj(bool multithreaded) {
111     if (multithreaded) llvm_start_multithreaded();
112   }
113   ~llvm_shutdown_obj() { llvm_shutdown(); }
114 };
115
116 }
117
118 #endif