]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/lib/Support/ManagedStatic.cpp
MFV r357163:
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / lib / Support / ManagedStatic.cpp
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/Mutex.h"
16 #include "llvm/Support/MutexGuard.h"
17 #include "llvm/Support/Threading.h"
18 #include <cassert>
19 using namespace llvm;
20
21 static const ManagedStaticBase *StaticList = nullptr;
22 static sys::Mutex *ManagedStaticMutex = nullptr;
23 static llvm::once_flag mutex_init_flag;
24
25 static void initializeMutex() {
26   ManagedStaticMutex = new sys::Mutex();
27 }
28
29 static sys::Mutex* getManagedStaticMutex() {
30   llvm::call_once(mutex_init_flag, initializeMutex);
31   return ManagedStaticMutex;
32 }
33
34 void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(),
35                                               void (*Deleter)(void*)) const {
36   assert(Creator);
37   if (llvm_is_multithreaded()) {
38     MutexGuard Lock(*getManagedStaticMutex());
39
40     if (!Ptr.load(std::memory_order_relaxed)) {
41       void *Tmp = Creator();
42
43       Ptr.store(Tmp, std::memory_order_release);
44       DeleterFn = Deleter;
45
46       // Add to list of managed statics.
47       Next = StaticList;
48       StaticList = this;
49     }
50   } else {
51     assert(!Ptr && !DeleterFn && !Next &&
52            "Partially initialized ManagedStatic!?");
53     Ptr = Creator();
54     DeleterFn = Deleter;
55
56     // Add to list of managed statics.
57     Next = StaticList;
58     StaticList = this;
59   }
60 }
61
62 void ManagedStaticBase::destroy() const {
63   assert(DeleterFn && "ManagedStatic not initialized correctly!");
64   assert(StaticList == this &&
65          "Not destroyed in reverse order of construction?");
66   // Unlink from list.
67   StaticList = Next;
68   Next = nullptr;
69
70   // Destroy memory.
71   DeleterFn(Ptr);
72
73   // Cleanup.
74   Ptr = nullptr;
75   DeleterFn = nullptr;
76 }
77
78 /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
79 void llvm::llvm_shutdown() {
80   MutexGuard Lock(*getManagedStaticMutex());
81
82   while (StaticList)
83     StaticList->destroy();
84 }