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