blob: fb7cd070c42de56b83709da922c96cd64dc5cfb2 [file] [log] [blame]
Chris Lattner9daff492006-09-28 00:31:55 +00001//===-- ManagedStatic.cpp - Static Global wrapper -------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattnerf3ebc3f2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Chris Lattner9daff492006-09-28 00:31:55 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the ManagedStatic class and llvm_shutdown().
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/Support/ManagedStatic.h"
Owen Andersonb9a4a572009-05-20 00:39:20 +000015#include "llvm/Config/config.h"
Zachary Turnerd119fa02014-06-21 00:24:51 +000016#include "llvm/Support/Mutex.h"
17#include "llvm/Support/MutexGuard.h"
Chandler Carruthdd146382016-06-02 18:22:12 +000018#include "llvm/Support/Threading.h"
Chris Lattner9daff492006-09-28 00:31:55 +000019#include <cassert>
20using namespace llvm;
21
Craig Topperc10719f2014-04-07 04:17:22 +000022static const ManagedStaticBase *StaticList = nullptr;
Chandler Carruthdd146382016-06-02 18:22:12 +000023static sys::Mutex *ManagedStaticMutex = nullptr;
Kamil Rytarowski5d2bd8d2017-02-05 21:13:06 +000024static llvm::once_flag mutex_init_flag;
Chris Lattner9daff492006-09-28 00:31:55 +000025
Chandler Carruthdd146382016-06-02 18:22:12 +000026static void initializeMutex() {
27 ManagedStaticMutex = new sys::Mutex();
28}
29
30static sys::Mutex* getManagedStaticMutex() {
Zachary Turnerd119fa02014-06-21 00:24:51 +000031 // 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.
Chandler Carruthfe1ffb92016-06-04 19:57:55 +000034 llvm::call_once(mutex_init_flag, initializeMutex);
Zachary Turnerd119fa02014-06-21 00:24:51 +000035 return ManagedStaticMutex;
Zachary Turner6ad24442014-06-19 16:17:42 +000036}
37
Owen Andersonb9a4a572009-05-20 00:39:20 +000038void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(),
Chris Lattner9daff492006-09-28 00:31:55 +000039 void (*Deleter)(void*)) const {
David Blaikie5b015932014-04-17 20:30:35 +000040 assert(Creator);
Owen Anderson4cb4b612009-06-16 17:33:51 +000041 if (llvm_is_multithreaded()) {
Chandler Carruthdd146382016-06-02 18:22:12 +000042 MutexGuard Lock(*getManagedStaticMutex());
Owen Andersonb9a4a572009-05-20 00:39:20 +000043
Benjamin Kramer832d0422016-06-29 15:04:07 +000044 if (!Ptr.load(std::memory_order_relaxed)) {
45 void *Tmp = Creator();
Owen Andersonb9a4a572009-05-20 00:39:20 +000046
Benjamin Kramer832d0422016-06-29 15:04:07 +000047 Ptr.store(Tmp, std::memory_order_release);
Owen Andersonb9a4a572009-05-20 00:39:20 +000048 DeleterFn = Deleter;
49
50 // Add to list of managed statics.
51 Next = StaticList;
52 StaticList = this;
53 }
Owen Andersonb9a4a572009-05-20 00:39:20 +000054 } else {
Craig Topper2617dcc2014-04-15 06:32:26 +000055 assert(!Ptr && !DeleterFn && !Next &&
Bill Wendling09f17a82009-05-30 01:09:53 +000056 "Partially initialized ManagedStatic!?");
David Blaikie5b015932014-04-17 20:30:35 +000057 Ptr = Creator();
Owen Andersonb9a4a572009-05-20 00:39:20 +000058 DeleterFn = Deleter;
Chris Lattner9daff492006-09-28 00:31:55 +000059
Owen Andersonb9a4a572009-05-20 00:39:20 +000060 // Add to list of managed statics.
61 Next = StaticList;
62 StaticList = this;
63 }
Chris Lattner9daff492006-09-28 00:31:55 +000064}
65
66void ManagedStaticBase::destroy() const {
Chris Lattner4510c992007-02-20 06:18:57 +000067 assert(DeleterFn && "ManagedStatic not initialized correctly!");
Chris Lattner9daff492006-09-28 00:31:55 +000068 assert(StaticList == this &&
69 "Not destroyed in reverse order of construction?");
70 // Unlink from list.
71 StaticList = Next;
Craig Topperc10719f2014-04-07 04:17:22 +000072 Next = nullptr;
Chris Lattner9daff492006-09-28 00:31:55 +000073
74 // Destroy memory.
75 DeleterFn(Ptr);
76
77 // Cleanup.
Craig Topperc10719f2014-04-07 04:17:22 +000078 Ptr = nullptr;
79 DeleterFn = nullptr;
Chris Lattner9daff492006-09-28 00:31:55 +000080}
81
82/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
Chris Lattneradf409532006-09-29 18:43:14 +000083void llvm::llvm_shutdown() {
Chandler Carruthdd146382016-06-02 18:22:12 +000084 MutexGuard Lock(*getManagedStaticMutex());
Zachary Turner6ad24442014-06-19 16:17:42 +000085
NAKAMURA Takumi256d37a2014-10-14 15:58:16 +000086 while (StaticList)
87 StaticList->destroy();
Chris Lattner9daff492006-09-28 00:31:55 +000088}