Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
3.4 KiB

  1. //===-- llvm/Support/ManagedStatic.h - Static Global wrapper ----*- C++ -*-===//
  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 defines the ManagedStatic class and the llvm_shutdown() function.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_SUPPORT_MANAGED_STATIC_H
  14. #define LLVM_SUPPORT_MANAGED_STATIC_H
  15. #include "llvm/Support/Atomic.h"
  16. #include "llvm/Support/Threading.h"
  17. #include "llvm/Support/Valgrind.h"
  18. namespace llvm {
  19. /// object_creator - Helper method for ManagedStatic.
  20. template<class C>
  21. void* object_creator() {
  22. return new C();
  23. }
  24. /// object_deleter - Helper method for ManagedStatic.
  25. ///
  26. template<typename T> struct object_deleter {
  27. static void call(void * Ptr) { delete (T*)Ptr; }
  28. };
  29. template<typename T, size_t N> struct object_deleter<T[N]> {
  30. static void call(void * Ptr) { delete[] (T*)Ptr; }
  31. };
  32. /// ManagedStaticBase - Common base class for ManagedStatic instances.
  33. class ManagedStaticBase {
  34. protected:
  35. // This should only be used as a static variable, which guarantees that this
  36. // will be zero initialized.
  37. mutable void *Ptr;
  38. mutable void (*DeleterFn)(void*);
  39. mutable const ManagedStaticBase *Next;
  40. void RegisterManagedStatic(void *(*creator)(), void (*deleter)(void*)) const;
  41. public:
  42. /// isConstructed - Return true if this object has not been created yet.
  43. bool isConstructed() const { return Ptr != 0; }
  44. void destroy() const;
  45. };
  46. /// ManagedStatic - This transparently changes the behavior of global statics to
  47. /// be lazily constructed on demand (good for reducing startup times of dynamic
  48. /// libraries that link in LLVM components) and for making destruction be
  49. /// explicit through the llvm_shutdown() function call.
  50. ///
  51. template<class C>
  52. class ManagedStatic : public ManagedStaticBase {
  53. public:
  54. // Accessors.
  55. C &operator*() {
  56. void* tmp = Ptr;
  57. if (llvm_is_multithreaded()) sys::MemoryFence();
  58. if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
  59. TsanHappensAfter(this);
  60. return *static_cast<C*>(Ptr);
  61. }
  62. C *operator->() {
  63. void* tmp = Ptr;
  64. if (llvm_is_multithreaded()) sys::MemoryFence();
  65. if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
  66. TsanHappensAfter(this);
  67. return static_cast<C*>(Ptr);
  68. }
  69. const C &operator*() const {
  70. void* tmp = Ptr;
  71. if (llvm_is_multithreaded()) sys::MemoryFence();
  72. if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
  73. TsanHappensAfter(this);
  74. return *static_cast<C*>(Ptr);
  75. }
  76. const C *operator->() const {
  77. void* tmp = Ptr;
  78. if (llvm_is_multithreaded()) sys::MemoryFence();
  79. if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
  80. TsanHappensAfter(this);
  81. return static_cast<C*>(Ptr);
  82. }
  83. };
  84. /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
  85. void llvm_shutdown();
  86. /// llvm_shutdown_obj - This is a simple helper class that calls
  87. /// llvm_shutdown() when it is destroyed.
  88. struct llvm_shutdown_obj {
  89. llvm_shutdown_obj() { }
  90. explicit llvm_shutdown_obj(bool multithreaded) {
  91. if (multithreaded) llvm_start_multithreaded();
  92. }
  93. ~llvm_shutdown_obj() { llvm_shutdown(); }
  94. };
  95. }
  96. #endif