1//===-- ManagedStatic.cpp - Static Global wrapper -------------------------===//
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 implements the ManagedStatic class and llvm_shutdown().
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/Support/ManagedStatic.h"
15#include "llvm/Config/config.h"
16#include "llvm/Support/Atomic.h"
17#include <cassert>
18using namespace llvm;
19
20static const ManagedStaticBase *StaticList = 0;
21
22void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(),
23                                              void (*Deleter)(void*)) const {
24  if (llvm_is_multithreaded()) {
25    llvm_acquire_global_lock();
26
27    if (Ptr == 0) {
28      void* tmp = Creator ? Creator() : 0;
29
30      sys::MemoryFence();
31      Ptr = tmp;
32      DeleterFn = Deleter;
33
34      // Add to list of managed statics.
35      Next = StaticList;
36      StaticList = this;
37    }
38
39    llvm_release_global_lock();
40  } else {
41    assert(Ptr == 0 && DeleterFn == 0 && Next == 0 &&
42           "Partially initialized ManagedStatic!?");
43    Ptr = Creator ? Creator() : 0;
44    DeleterFn = Deleter;
45
46    // Add to list of managed statics.
47    Next = StaticList;
48    StaticList = this;
49  }
50}
51
52void ManagedStaticBase::destroy() const {
53  assert(DeleterFn && "ManagedStatic not initialized correctly!");
54  assert(StaticList == this &&
55         "Not destroyed in reverse order of construction?");
56  // Unlink from list.
57  StaticList = Next;
58  Next = 0;
59
60  // Destroy memory.
61  DeleterFn(Ptr);
62
63  // Cleanup.
64  Ptr = 0;
65  DeleterFn = 0;
66}
67
68/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
69void llvm::llvm_shutdown() {
70  while (StaticList)
71    StaticList->destroy();
72
73  if (llvm_is_multithreaded()) llvm_stop_multithreaded();
74}
75
76