xref: /aosp_15_r20/external/swiftshader/third_party/llvm-subzero/lib/Support/ManagedStatic.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1 //===-- ManagedStatic.cpp - Static Global wrapper -------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the ManagedStatic class and llvm_shutdown().
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/Support/ManagedStatic.h"
15 #include "llvm/Support/Threading.h"
16 #include <cassert>
17 #include <mutex>
18 using namespace llvm;
19 
20 static const ManagedStaticBase *StaticList = nullptr;
21 static std::recursive_mutex *ManagedStaticMutex = nullptr;
22 LLVM_DEFINE_ONCE_FLAG(mutex_init_flag);
23 
24 #if 0
25 
26 static void initializeMutex() {
27   ManagedStaticMutex = new std::recursive_mutex();
28 }
29 
30 static std::recursive_mutex* getManagedStaticMutex() {
31   // 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.
34   llvm::call_once(mutex_init_flag, initializeMutex);
35   return ManagedStaticMutex;
36 }
37 
38 #else
39 
40 // SwiftShader: from https://reviews.llvm.org/D83372
getManagedStaticMutex()41 static std::recursive_mutex *getManagedStaticMutex() {
42   static std::recursive_mutex m;
43   return &m;
44 }
45 
46 #endif
47 
RegisterManagedStatic(void * (* Creator)(),void (* Deleter)(void *)) const48 void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(),
49                                               void (*Deleter)(void*)) const {
50   assert(Creator);
51   std::lock_guard<std::recursive_mutex> Lock(*getManagedStaticMutex());
52 
53   if (!Ptr.load(std::memory_order_relaxed)) {
54     void *Tmp = Creator();
55 
56     Ptr.store(Tmp, std::memory_order_release);
57     DeleterFn = Deleter;
58 
59     // Add to list of managed statics.
60     Next = StaticList;
61     StaticList = this;
62   }
63 }
64 
destroy() const65 void ManagedStaticBase::destroy() const {
66   assert(DeleterFn && "ManagedStatic not initialized correctly!");
67   assert(StaticList == this &&
68          "Not destroyed in reverse order of construction?");
69   // Unlink from list.
70   StaticList = Next;
71   Next = nullptr;
72 
73   // Destroy memory.
74   DeleterFn(Ptr);
75 
76   // Cleanup.
77   Ptr = nullptr;
78   DeleterFn = nullptr;
79 }
80 
81 /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
llvm_shutdown()82 void llvm::llvm_shutdown() {
83   // SwiftShader: from https://reviews.llvm.org/D83372
84   // This may be called after the mutex is destroyed. Instead of fixing this,
85   // don't bother locking the mutex, and require llvm_shutdown to be called from
86   // exactly one thread.
87   // std::lock_guard<std::recursive_mutex> Lock(*getManagedStaticMutex());
88 
89   while (StaticList)
90     StaticList->destroy();
91 }
92