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/Support/Atomic.h"
18#include "llvm/Support/Threading.h"
19
20namespace llvm {
21
22/// object_creator - Helper method for ManagedStatic.
23template<class C>
24void* object_creator() {
25  return new C();
26}
27
28/// object_deleter - Helper method for ManagedStatic.
29///
30template<typename T> struct object_deleter {
31  static void call(void * Ptr) { delete (T*)Ptr; }
32};
33template<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.
38class ManagedStaticBase {
39protected:
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;
47public:
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///
59template<class C>
60class ManagedStatic : public ManagedStaticBase {
61public:
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.
95void llvm_shutdown();
96
97
98/// llvm_shutdown_obj - This is a simple helper class that calls
99/// llvm_shutdown() when it is destroyed.
100struct 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
111