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> 20using namespace llvm; 21 22static const ManagedStaticBase *StaticList = nullptr; 23static sys::Mutex *ManagedStaticMutex = nullptr; 24LLVM_DEFINE_ONCE_FLAG(mutex_init_flag); 25 26static void initializeMutex() { 27 ManagedStaticMutex = new sys::Mutex(); 28} 29 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 38void 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 66void 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. 83void llvm::llvm_shutdown() { 84 MutexGuard Lock(*getManagedStaticMutex()); 85 86 while (StaticList) 87 StaticList->destroy(); 88} 89