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 LLVM_DEFINE_ONCE_FLAG(mutex_init_flag); 25 initializeMutex()26static void initializeMutex() { 27 ManagedStaticMutex = new sys::Mutex(); 28 } 29 getManagedStaticMutex()30static sys::Mutex* getManagedStaticMutex() { 31 // We need to use a function local static here, since this can get called 32 // during a static constructor and we need to guarantee that it's initialized 33 // correctly. 34 llvm::call_once(mutex_init_flag, initializeMutex); 35 return ManagedStaticMutex; 36 } 37 RegisterManagedStatic(void * (* Creator)(),void (* Deleter)(void *)) const38void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(), 39 void (*Deleter)(void*)) const { 40 assert(Creator); 41 if (llvm_is_multithreaded()) { 42 MutexGuard Lock(*getManagedStaticMutex()); 43 44 if (!Ptr.load(std::memory_order_relaxed)) { 45 void *Tmp = Creator(); 46 47 Ptr.store(Tmp, std::memory_order_release); 48 DeleterFn = Deleter; 49 50 // Add to list of managed statics. 51 Next = StaticList; 52 StaticList = this; 53 } 54 } else { 55 assert(!Ptr && !DeleterFn && !Next && 56 "Partially initialized ManagedStatic!?"); 57 Ptr = Creator(); 58 DeleterFn = Deleter; 59 60 // Add to list of managed statics. 61 Next = StaticList; 62 StaticList = this; 63 } 64 } 65 destroy() const66void ManagedStaticBase::destroy() const { 67 assert(DeleterFn && "ManagedStatic not initialized correctly!"); 68 assert(StaticList == this && 69 "Not destroyed in reverse order of construction?"); 70 // Unlink from list. 71 StaticList = Next; 72 Next = nullptr; 73 74 // Destroy memory. 75 DeleterFn(Ptr); 76 77 // Cleanup. 78 Ptr = nullptr; 79 DeleterFn = nullptr; 80 } 81 82 /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables. llvm_shutdown()83void llvm::llvm_shutdown() { 84 MutexGuard Lock(*getManagedStaticMutex()); 85 86 while (StaticList) 87 StaticList->destroy(); 88 } 89