Mutex.h 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #pragma once
  4. #include <mutex>
  5. #include <shared_mutex>
  6. #include <thread>
  7. #include <Core/Profiler.h>
  8. namespace JPH {
  9. #if defined(JPH_ENABLE_ASSERTS) || defined(JPH_PROFILE_ENABLED) || defined(JPH_EXTERNAL_PROFILE)
  10. /// Very simple wrapper around std::mutex which tracks lock contention in the profiler
  11. /// and asserts that locks/unlocks take place on the same thread
  12. class Mutex : public mutex
  13. {
  14. public:
  15. inline bool try_lock()
  16. {
  17. JPH_ASSERT(mLockedThreadID != this_thread::get_id());
  18. if (mutex::try_lock())
  19. {
  20. JPH_IF_ENABLE_ASSERTS(mLockedThreadID = this_thread::get_id();)
  21. return true;
  22. }
  23. return false;
  24. }
  25. inline void lock()
  26. {
  27. if (!try_lock())
  28. {
  29. JPH_PROFILE("Lock", 0xff00ffff);
  30. mutex::lock();
  31. JPH_IF_ENABLE_ASSERTS(mLockedThreadID = this_thread::get_id();)
  32. }
  33. }
  34. inline void unlock()
  35. {
  36. JPH_ASSERT(mLockedThreadID == this_thread::get_id());
  37. JPH_IF_ENABLE_ASSERTS(mLockedThreadID = thread::id();)
  38. mutex::unlock();
  39. }
  40. #ifdef JPH_ENABLE_ASSERTS
  41. inline bool is_locked()
  42. {
  43. return mLockedThreadID != thread::id();
  44. }
  45. #endif // JPH_ENABLE_ASSERTS
  46. private:
  47. JPH_IF_ENABLE_ASSERTS(thread::id mLockedThreadID;)
  48. };
  49. /// Very simple wrapper around std::shared_mutex which tracks lock contention in the profiler
  50. /// and asserts that locks/unlocks take place on the same thread
  51. class SharedMutex : public shared_mutex
  52. {
  53. public:
  54. inline bool try_lock()
  55. {
  56. JPH_ASSERT(mLockedThreadID != this_thread::get_id());
  57. if (shared_mutex::try_lock())
  58. {
  59. JPH_IF_ENABLE_ASSERTS(mLockedThreadID = this_thread::get_id();)
  60. return true;
  61. }
  62. return false;
  63. }
  64. inline void lock()
  65. {
  66. if (!try_lock())
  67. {
  68. JPH_PROFILE("Lock", 0xff00ffff);
  69. shared_mutex::lock();
  70. JPH_IF_ENABLE_ASSERTS(mLockedThreadID = this_thread::get_id();)
  71. }
  72. }
  73. inline void unlock()
  74. {
  75. JPH_ASSERT(mLockedThreadID == this_thread::get_id());
  76. JPH_IF_ENABLE_ASSERTS(mLockedThreadID = thread::id();)
  77. shared_mutex::unlock();
  78. }
  79. #ifdef JPH_ENABLE_ASSERTS
  80. inline bool is_locked()
  81. {
  82. return mLockedThreadID != thread::id();
  83. }
  84. #endif // JPH_ENABLE_ASSERTS
  85. inline void lock_shared()
  86. {
  87. if (!try_lock_shared())
  88. {
  89. JPH_PROFILE("LockShared", 0xff00ffff);
  90. shared_mutex::lock_shared();
  91. }
  92. }
  93. private:
  94. JPH_IF_ENABLE_ASSERTS(thread::id mLockedThreadID;)
  95. };
  96. #else
  97. using Mutex = mutex;
  98. using SharedMutex = shared_mutex;
  99. #endif
  100. } // JPH