Line data Source code
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/Mutex.h"
17 : #include "llvm/Support/MutexGuard.h"
18 : #include "llvm/Support/Threading.h"
19 : #include <cassert>
20 : using namespace llvm;
21 :
22 : static const ManagedStaticBase *StaticList = nullptr;
23 : static sys::Mutex *ManagedStaticMutex = nullptr;
24 : static llvm::once_flag mutex_init_flag;
25 :
26 181221 : static void initializeMutex() {
27 181221 : ManagedStaticMutex = new sys::Mutex();
28 181221 : }
29 :
30 : static sys::Mutex* getManagedStaticMutex() {
31 : llvm::call_once(mutex_init_flag, initializeMutex);
32 1514565 : return ManagedStaticMutex;
33 : }
34 :
35 1349297 : void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(),
36 : void (*Deleter)(void*)) const {
37 : assert(Creator);
38 1349297 : if (llvm_is_multithreaded()) {
39 : MutexGuard Lock(*getManagedStaticMutex());
40 :
41 1349297 : if (!Ptr.load(std::memory_order_relaxed)) {
42 1349297 : void *Tmp = Creator();
43 :
44 : Ptr.store(Tmp, std::memory_order_release);
45 1349297 : DeleterFn = Deleter;
46 :
47 : // Add to list of managed statics.
48 1349297 : Next = StaticList;
49 1349297 : StaticList = this;
50 : }
51 : } else {
52 : assert(!Ptr && !DeleterFn && !Next &&
53 : "Partially initialized ManagedStatic!?");
54 0 : Ptr = Creator();
55 0 : DeleterFn = Deleter;
56 :
57 : // Add to list of managed statics.
58 0 : Next = StaticList;
59 0 : StaticList = this;
60 : }
61 1349297 : }
62 :
63 1251686 : void ManagedStaticBase::destroy() const {
64 : assert(DeleterFn && "ManagedStatic not initialized correctly!");
65 : assert(StaticList == this &&
66 : "Not destroyed in reverse order of construction?");
67 : // Unlink from list.
68 1251686 : StaticList = Next;
69 1251686 : Next = nullptr;
70 :
71 : // Destroy memory.
72 2503372 : DeleterFn(Ptr);
73 :
74 : // Cleanup.
75 : Ptr = nullptr;
76 1251686 : DeleterFn = nullptr;
77 1251686 : }
78 :
79 : /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
80 165268 : void llvm::llvm_shutdown() {
81 : MutexGuard Lock(*getManagedStaticMutex());
82 :
83 1416954 : while (StaticList)
84 1251686 : StaticList->destroy();
85 165268 : }
|