blob: acd5b1a70183c420367646a679048b933973356f [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"
Benjamin Kramer17388a62014-03-03 18:02:34 +000016#include "llvm/Support/Atomic.h"
Chris Lattner9daff492006-09-28 00:31:55 +000017#include <cassert>
18using namespace llvm;
19
Craig Topperc10719f2014-04-07 04:17:22 +000020static const ManagedStaticBase *StaticList = nullptr;
Chris Lattner9daff492006-09-28 00:31:55 +000021
Owen Andersonb9a4a572009-05-20 00:39:20 +000022void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(),
Chris Lattner9daff492006-09-28 00:31:55 +000023 void (*Deleter)(void*)) const {
Owen Anderson4cb4b612009-06-16 17:33:51 +000024 if (llvm_is_multithreaded()) {
25 llvm_acquire_global_lock();
Owen Andersonb9a4a572009-05-20 00:39:20 +000026
Craig Topper8d399f82014-04-09 04:20:00 +000027 if (!Ptr) {
Craig Topperc10719f2014-04-07 04:17:22 +000028 void* tmp = Creator ? Creator() : nullptr;
Owen Andersonb9a4a572009-05-20 00:39:20 +000029
Nick Lewyckyfe856112011-11-14 20:50:16 +000030 TsanHappensBefore(this);
Benjamin Kramer17388a62014-03-03 18:02:34 +000031 sys::MemoryFence();
Nick Lewyckyfe856112011-11-14 20:50:16 +000032
33 // This write is racy against the first read in the ManagedStatic
34 // accessors. The race is benign because it does a second read after a
35 // memory fence, at which point it isn't possible to get a partial value.
36 TsanIgnoreWritesBegin();
Owen Andersonb9a4a572009-05-20 00:39:20 +000037 Ptr = tmp;
Nick Lewyckyfe856112011-11-14 20:50:16 +000038 TsanIgnoreWritesEnd();
Owen Andersonb9a4a572009-05-20 00:39:20 +000039 DeleterFn = Deleter;
40
41 // Add to list of managed statics.
42 Next = StaticList;
43 StaticList = this;
44 }
45
Owen Anderson4cb4b612009-06-16 17:33:51 +000046 llvm_release_global_lock();
Owen Andersonb9a4a572009-05-20 00:39:20 +000047 } else {
Craig Topper2617dcc2014-04-15 06:32:26 +000048 assert(!Ptr && !DeleterFn && !Next &&
Bill Wendling09f17a82009-05-30 01:09:53 +000049 "Partially initialized ManagedStatic!?");
Craig Topperc10719f2014-04-07 04:17:22 +000050 Ptr = Creator ? Creator() : nullptr;
Owen Andersonb9a4a572009-05-20 00:39:20 +000051 DeleterFn = Deleter;
Chris Lattner9daff492006-09-28 00:31:55 +000052
Owen Andersonb9a4a572009-05-20 00:39:20 +000053 // Add to list of managed statics.
54 Next = StaticList;
55 StaticList = this;
56 }
Chris Lattner9daff492006-09-28 00:31:55 +000057}
58
59void ManagedStaticBase::destroy() const {
Chris Lattner4510c992007-02-20 06:18:57 +000060 assert(DeleterFn && "ManagedStatic not initialized correctly!");
Chris Lattner9daff492006-09-28 00:31:55 +000061 assert(StaticList == this &&
62 "Not destroyed in reverse order of construction?");
63 // Unlink from list.
64 StaticList = Next;
Craig Topperc10719f2014-04-07 04:17:22 +000065 Next = nullptr;
Chris Lattner9daff492006-09-28 00:31:55 +000066
67 // Destroy memory.
68 DeleterFn(Ptr);
69
70 // Cleanup.
Craig Topperc10719f2014-04-07 04:17:22 +000071 Ptr = nullptr;
72 DeleterFn = nullptr;
Chris Lattner9daff492006-09-28 00:31:55 +000073}
74
75/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
Chris Lattneradf409532006-09-29 18:43:14 +000076void llvm::llvm_shutdown() {
Chris Lattner9daff492006-09-28 00:31:55 +000077 while (StaticList)
78 StaticList->destroy();
Owen Andersonb9a4a572009-05-20 00:39:20 +000079
Owen Anderson4cb4b612009-06-16 17:33:51 +000080 if (llvm_is_multithreaded()) llvm_stop_multithreaded();
Chris Lattner9daff492006-09-28 00:31:55 +000081}