1//===-- ManagedStatic.cpp - Static Global wrapper -------------------------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file implements the ManagedStatic class and llvm_shutdown(). 10// 11//===----------------------------------------------------------------------===// 12 13#include "llvm/Support/ManagedStatic.h" 14#include "llvm/Config/config.h" 15#include "llvm/Support/Threading.h" 16#include <cassert> 17#include <mutex> 18using namespace llvm; 19 20static const ManagedStaticBase *StaticList = nullptr; 21static std::recursive_mutex *ManagedStaticMutex = nullptr; 22static llvm::once_flag mutex_init_flag; 23 24static void initializeMutex() { 25 ManagedStaticMutex = new std::recursive_mutex(); 26} 27 28static std::recursive_mutex *getManagedStaticMutex() { 29 llvm::call_once(mutex_init_flag, initializeMutex); 30 return ManagedStaticMutex; 31} 32 33void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(), 34 void (*Deleter)(void*)) const { 35 assert(Creator); 36 if (llvm_is_multithreaded()) { 37 std::lock_guard<std::recursive_mutex> Lock(*getManagedStaticMutex()); 38 39 if (!Ptr.load(std::memory_order_relaxed)) { 40 void *Tmp = Creator(); 41 42 Ptr.store(Tmp, std::memory_order_release); 43 DeleterFn = Deleter; 44 45 // Add to list of managed statics. 46 Next = StaticList; 47 StaticList = this; 48 } 49 } else { 50 assert(!Ptr && !DeleterFn && !Next && 51 "Partially initialized ManagedStatic!?"); 52 Ptr = Creator(); 53 DeleterFn = Deleter; 54 55 // Add to list of managed statics. 56 Next = StaticList; 57 StaticList = this; 58 } 59} 60 61void ManagedStaticBase::destroy() const { 62 assert(DeleterFn && "ManagedStatic not initialized correctly!"); 63 assert(StaticList == this && 64 "Not destroyed in reverse order of construction?"); 65 // Unlink from list. 66 StaticList = Next; 67 Next = nullptr; 68 69 // Destroy memory. 70 DeleterFn(Ptr); 71 72 // Cleanup. 73 Ptr = nullptr; 74 DeleterFn = nullptr; 75} 76 77/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables. 78void llvm::llvm_shutdown() { 79 std::lock_guard<std::recursive_mutex> Lock(*getManagedStaticMutex()); 80 81 while (StaticList) 82 StaticList->destroy(); 83} 84