c19f8cb48596c660be0d3d1c0d0992c0edaced6a
[oota-llvm.git] / lib / Support / ManagedStatic.cpp
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 <cassert>
17 using namespace llvm;
18
19 static const ManagedStaticBase *StaticList = 0;
20
21 void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(),
22                                               void (*Deleter)(void*)) const {
23   if (llvm_is_multithreaded()) {
24     llvm_acquire_global_lock();
25
26     if (Ptr == 0) {
27       void* tmp = Creator ? Creator() : 0;
28
29       TsanHappensBefore(this);
30       std::atomic_thread_fence(std::memory_order_seq_cst);
31
32       // This write is racy against the first read in the ManagedStatic
33       // accessors. The race is benign because it does a second read after a
34       // memory fence, at which point it isn't possible to get a partial value.
35       TsanIgnoreWritesBegin();
36       Ptr = tmp;
37       TsanIgnoreWritesEnd();
38       DeleterFn = Deleter;
39       
40       // Add to list of managed statics.
41       Next = StaticList;
42       StaticList = this;
43     }
44
45     llvm_release_global_lock();
46   } else {
47     assert(Ptr == 0 && DeleterFn == 0 && Next == 0 &&
48            "Partially initialized ManagedStatic!?");
49     Ptr = Creator ? Creator() : 0;
50     DeleterFn = Deleter;
51   
52     // Add to list of managed statics.
53     Next = StaticList;
54     StaticList = this;
55   }
56 }
57
58 void ManagedStaticBase::destroy() const {
59   assert(DeleterFn && "ManagedStatic not initialized correctly!");
60   assert(StaticList == this &&
61          "Not destroyed in reverse order of construction?");
62   // Unlink from list.
63   StaticList = Next;
64   Next = 0;
65
66   // Destroy memory.
67   DeleterFn(Ptr);
68   
69   // Cleanup.
70   Ptr = 0;
71   DeleterFn = 0;
72 }
73
74 /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
75 void llvm::llvm_shutdown() {
76   while (StaticList)
77     StaticList->destroy();
78
79   if (llvm_is_multithreaded()) llvm_stop_multithreaded();
80 }