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