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