Revert "System: Add SwapByteOrder and update Support/MathExtras.h to use it."
[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/System/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<typename T> struct object_deleter {
31   static void call(void * Ptr) { delete (T*)Ptr; }
32 };
33 template<typename T, size_t N> struct object_deleter<T[N]> {
34   static void call(void * Ptr) { delete[] (T*)Ptr; }
35 };
36
37 /// ManagedStaticBase - Common base class for ManagedStatic instances.
38 class ManagedStaticBase {
39 protected:
40   // This should only be used as a static variable, which guarantees that this
41   // will be zero initialized.
42   mutable void *Ptr;
43   mutable void (*DeleterFn)(void*);
44   mutable const ManagedStaticBase *Next;
45
46   void RegisterManagedStatic(void *(*creator)(), void (*deleter)(void*)) const;
47 public:
48   /// isConstructed - Return true if this object has not been created yet.
49   bool isConstructed() const { return Ptr != 0; }
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>
60 class ManagedStatic : public ManagedStaticBase {
61 public:
62
63   // Accessors.
64   C &operator*() {
65     void* tmp = Ptr;
66     if (llvm_is_multithreaded()) sys::MemoryFence();
67     if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
68
69     return *static_cast<C*>(Ptr);
70   }
71   C *operator->() {
72     void* tmp = Ptr;
73     if (llvm_is_multithreaded()) sys::MemoryFence();
74     if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
75
76     return static_cast<C*>(Ptr);
77   }
78   const C &operator*() const {
79     void* tmp = Ptr;
80     if (llvm_is_multithreaded()) sys::MemoryFence();
81     if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
82
83     return *static_cast<C*>(Ptr);
84   }
85   const C *operator->() const {
86     void* tmp = Ptr;
87     if (llvm_is_multithreaded()) sys::MemoryFence();
88     if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
89
90     return static_cast<C*>(Ptr);
91   }
92 };
93
94 /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
95 void llvm_shutdown();
96
97
98 /// llvm_shutdown_obj - This is a simple helper class that calls
99 /// llvm_shutdown() when it is destroyed.
100 struct llvm_shutdown_obj {
101   llvm_shutdown_obj() { }
102   explicit llvm_shutdown_obj(bool multithreaded) {
103     if (multithreaded) llvm_start_multithreaded();
104   }
105   ~llvm_shutdown_obj() { llvm_shutdown(); }
106 };
107
108 }
109
110 #endif