ManagedStatic.cpp 2.3 KB

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