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