blob: 053493f72fb5eeba9cc623201aba80ccc62a5f79 [file] [log] [blame]
Chris Lattner9daff492006-09-28 00:31:55 +00001//===-- ManagedStatic.cpp - Static Global wrapper -------------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Chris Lattner9daff492006-09-28 00:31:55 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the ManagedStatic class and llvm_shutdown().
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/Support/ManagedStatic.h"
Owen Andersonb9a4a572009-05-20 00:39:20 +000014#include "llvm/Config/config.h"
Chandler Carruthdd146382016-06-02 18:22:12 +000015#include "llvm/Support/Threading.h"
Chris Lattner9daff492006-09-28 00:31:55 +000016#include <cassert>
Benjamin Kramer3d5360a2019-08-07 10:57:25 +000017#include <mutex>
Chris Lattner9daff492006-09-28 00:31:55 +000018using namespace llvm;
19
Craig Topperc10719f2014-04-07 04:17:22 +000020static const ManagedStaticBase *StaticList = nullptr;
Benjamin Kramer928071a2019-08-19 19:49:57 +000021static std::recursive_mutex *ManagedStaticMutex = nullptr;
Kamil Rytarowski5d2bd8d2017-02-05 21:13:06 +000022static llvm::once_flag mutex_init_flag;
Chris Lattner9daff492006-09-28 00:31:55 +000023
Chandler Carruthdd146382016-06-02 18:22:12 +000024static void initializeMutex() {
Benjamin Kramer928071a2019-08-19 19:49:57 +000025 ManagedStaticMutex = new std::recursive_mutex();
Chandler Carruthdd146382016-06-02 18:22:12 +000026}
27
Benjamin Kramer928071a2019-08-19 19:49:57 +000028static std::recursive_mutex *getManagedStaticMutex() {
Chandler Carruthfe1ffb92016-06-04 19:57:55 +000029 llvm::call_once(mutex_init_flag, initializeMutex);
Zachary Turnerd119fa02014-06-21 00:24:51 +000030 return ManagedStaticMutex;
Zachary Turner6ad24442014-06-19 16:17:42 +000031}
32
Owen Andersonb9a4a572009-05-20 00:39:20 +000033void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(),
Chris Lattner9daff492006-09-28 00:31:55 +000034 void (*Deleter)(void*)) const {
David Blaikie5b015932014-04-17 20:30:35 +000035 assert(Creator);
Owen Anderson4cb4b612009-06-16 17:33:51 +000036 if (llvm_is_multithreaded()) {
Benjamin Kramer928071a2019-08-19 19:49:57 +000037 std::lock_guard<std::recursive_mutex> Lock(*getManagedStaticMutex());
Owen Andersonb9a4a572009-05-20 00:39:20 +000038
Benjamin Kramer832d0422016-06-29 15:04:07 +000039 if (!Ptr.load(std::memory_order_relaxed)) {
40 void *Tmp = Creator();
Owen Andersonb9a4a572009-05-20 00:39:20 +000041
Benjamin Kramer832d0422016-06-29 15:04:07 +000042 Ptr.store(Tmp, std::memory_order_release);
Owen Andersonb9a4a572009-05-20 00:39:20 +000043 DeleterFn = Deleter;
Fangrui Songf78650a2018-07-30 19:41:25 +000044
Owen Andersonb9a4a572009-05-20 00:39:20 +000045 // Add to list of managed statics.
46 Next = StaticList;
47 StaticList = this;
48 }
Owen Andersonb9a4a572009-05-20 00:39:20 +000049 } else {
Craig Topper2617dcc2014-04-15 06:32:26 +000050 assert(!Ptr && !DeleterFn && !Next &&
Bill Wendling09f17a82009-05-30 01:09:53 +000051 "Partially initialized ManagedStatic!?");
David Blaikie5b015932014-04-17 20:30:35 +000052 Ptr = Creator();
Owen Andersonb9a4a572009-05-20 00:39:20 +000053 DeleterFn = Deleter;
Fangrui Songf78650a2018-07-30 19:41:25 +000054
Owen Andersonb9a4a572009-05-20 00:39:20 +000055 // Add to list of managed statics.
56 Next = StaticList;
57 StaticList = this;
58 }
Chris Lattner9daff492006-09-28 00:31:55 +000059}
60
61void ManagedStaticBase::destroy() const {
Chris Lattner4510c992007-02-20 06:18:57 +000062 assert(DeleterFn && "ManagedStatic not initialized correctly!");
Chris Lattner9daff492006-09-28 00:31:55 +000063 assert(StaticList == this &&
64 "Not destroyed in reverse order of construction?");
65 // Unlink from list.
66 StaticList = Next;
Craig Topperc10719f2014-04-07 04:17:22 +000067 Next = nullptr;
Chris Lattner9daff492006-09-28 00:31:55 +000068
69 // Destroy memory.
70 DeleterFn(Ptr);
Fangrui Songf78650a2018-07-30 19:41:25 +000071
Chris Lattner9daff492006-09-28 00:31:55 +000072 // Cleanup.
Craig Topperc10719f2014-04-07 04:17:22 +000073 Ptr = nullptr;
74 DeleterFn = nullptr;
Chris Lattner9daff492006-09-28 00:31:55 +000075}
76
77/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
Chris Lattneradf409532006-09-29 18:43:14 +000078void llvm::llvm_shutdown() {
Benjamin Kramer928071a2019-08-19 19:49:57 +000079 std::lock_guard<std::recursive_mutex> Lock(*getManagedStaticMutex());
Zachary Turner6ad24442014-06-19 16:17:42 +000080
NAKAMURA Takumi256d37a2014-10-14 15:58:16 +000081 while (StaticList)
82 StaticList->destroy();
Chris Lattner9daff492006-09-28 00:31:55 +000083}