ManagedStatic.cpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  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. #include "llvm/Support/ManagedStatic.h"
  14. #include "llvm/Config/config.h"
  15. #include "llvm/Support/Atomic.h"
  16. #include "llvm/Support/MutexGuard.h"
  17. #include <cassert>
  18. using namespace llvm;
  19. static const ManagedStaticBase *StaticList = nullptr;
  20. void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(),
  21. void (*Deleter)(void*)) const {
  22. assert(Creator);
  23. if (llvm_is_multithreaded()) {
  24. llvm::MutexGuard Lock(llvm::llvm_get_global_lock());
  25. if (!Ptr) {
  26. void* tmp = Creator();
  27. TsanHappensBefore(this);
  28. sys::MemoryFence();
  29. // This write is racy against the first read in the ManagedStatic
  30. // accessors. The race is benign because it does a second read after a
  31. // memory fence, at which point it isn't possible to get a partial value.
  32. TsanIgnoreWritesBegin();
  33. Ptr = tmp;
  34. TsanIgnoreWritesEnd();
  35. DeleterFn = Deleter;
  36. // Add to list of managed statics.
  37. Next = StaticList;
  38. StaticList = this;
  39. }
  40. } else {
  41. assert(!Ptr && !DeleterFn && !Next &&
  42. "Partially initialized ManagedStatic!?");
  43. Ptr = Creator();
  44. DeleterFn = Deleter;
  45. // Add to list of managed statics.
  46. Next = StaticList;
  47. StaticList = this;
  48. }
  49. }
  50. void ManagedStaticBase::destroy() const {
  51. assert(DeleterFn && "ManagedStatic not initialized correctly!");
  52. assert(StaticList == this &&
  53. "Not destroyed in reverse order of construction?");
  54. // Unlink from list.
  55. StaticList = Next;
  56. Next = nullptr;
  57. // Destroy memory.
  58. DeleterFn(Ptr);
  59. // Cleanup.
  60. Ptr = nullptr;
  61. DeleterFn = nullptr;
  62. }
  63. /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
  64. void llvm::llvm_shutdown() {
  65. while (StaticList)
  66. StaticList->destroy();
  67. if (llvm_is_multithreaded()) llvm_stop_multithreaded();
  68. }