LLVM  14.0.0git
ManagedStatic.cpp
Go to the documentation of this file.
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 
14 #include "llvm/Config/config.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 
22 static std::recursive_mutex *getManagedStaticMutex() {
23  static std::recursive_mutex m;
24  return &m;
25 }
26 
28  void (*Deleter)(void*)) const {
29  assert(Creator);
30  if (llvm_is_multithreaded()) {
31  std::lock_guard<std::recursive_mutex> Lock(*getManagedStaticMutex());
32 
33  if (!Ptr.load(std::memory_order_relaxed)) {
34  void *Tmp = Creator();
35 
36  Ptr.store(Tmp, std::memory_order_release);
37  DeleterFn = Deleter;
38 
39  // Add to list of managed statics.
40  Next = StaticList;
41  StaticList = this;
42  }
43  } else {
44  assert(!Ptr && !DeleterFn && !Next &&
45  "Partially initialized ManagedStatic!?");
46  Ptr = Creator();
47  DeleterFn = Deleter;
48 
49  // Add to list of managed statics.
50  Next = StaticList;
51  StaticList = this;
52  }
53 }
54 
56  assert(DeleterFn && "ManagedStatic not initialized correctly!");
57  assert(StaticList == this &&
58  "Not destroyed in reverse order of construction?");
59  // Unlink from list.
60  StaticList = Next;
61  Next = nullptr;
62 
63  // Destroy memory.
64  DeleterFn(Ptr);
65 
66  // Cleanup.
67  Ptr = nullptr;
68  DeleterFn = nullptr;
69 }
70 
71 /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
72 /// IMPORTANT: it's only safe to call llvm_shutdown() in single thread,
73 /// without any other threads executing LLVM APIs.
74 /// llvm_shutdown() should be the last use of LLVM APIs.
76  while (StaticList)
78 }
StaticList
static const ManagedStaticBase * StaticList
Definition: ManagedStatic.cpp:20
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
ManagedStatic.h
llvm::ManagedStaticBase::Ptr
std::atomic< void * > Ptr
Definition: ManagedStatic.h:52
llvm::llvm_shutdown
void llvm_shutdown()
llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
Definition: ManagedStatic.cpp:75
llvm::Lock
static sys::Mutex Lock
Definition: NVPTXUtilities.cpp:39
llvm::ManagedStaticBase::Next
const ManagedStaticBase * Next
Definition: ManagedStatic.h:54
getManagedStaticMutex
static std::recursive_mutex * getManagedStaticMutex()
Definition: ManagedStatic.cpp:22
llvm::ManagedStaticBase
ManagedStaticBase - Common base class for ManagedStatic instances.
Definition: ManagedStatic.h:49
Threading.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::ManagedStaticBase::DeleterFn
void(* DeleterFn)(void *)
Definition: ManagedStatic.h:53
llvm::ManagedStaticBase::destroy
void destroy() const
Definition: ManagedStatic.cpp:55
llvm::ManagedStaticBase::RegisterManagedStatic
void RegisterManagedStatic(void *(*creator)(), void(*deleter)(void *)) const
Definition: ManagedStatic.cpp:27
llvm::llvm_is_multithreaded
bool llvm_is_multithreaded()
Returns true if LLVM is compiled with support for multi-threading, and false otherwise.
Definition: Threading.cpp:31