mutex.h 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // Copyright 2009-2020 Intel Corporation
  2. // SPDX-License-Identifier: Apache-2.0
  3. #pragma once
  4. #include "platform.h"
  5. #include "intrinsics.h"
  6. #include "atomic.h"
  7. namespace embree
  8. {
  9. /*! system mutex */
  10. class MutexSys {
  11. friend struct ConditionImplementation;
  12. public:
  13. MutexSys();
  14. ~MutexSys();
  15. private:
  16. MutexSys (const MutexSys& other) DELETED; // do not implement
  17. MutexSys& operator= (const MutexSys& other) DELETED; // do not implement
  18. public:
  19. void lock();
  20. bool try_lock();
  21. void unlock();
  22. protected:
  23. void* mutex;
  24. };
  25. /*! spinning mutex */
  26. class SpinLock
  27. {
  28. public:
  29. SpinLock ()
  30. : flag(false) {}
  31. __forceinline bool isLocked() {
  32. return flag.load();
  33. }
  34. __forceinline void lock()
  35. {
  36. while (true)
  37. {
  38. while (flag.load())
  39. {
  40. _mm_pause();
  41. _mm_pause();
  42. }
  43. bool expected = false;
  44. if (flag.compare_exchange_strong(expected,true,std::memory_order_acquire))
  45. break;
  46. }
  47. }
  48. __forceinline bool try_lock()
  49. {
  50. bool expected = false;
  51. if (flag.load() != expected) {
  52. return false;
  53. }
  54. return flag.compare_exchange_strong(expected,true,std::memory_order_acquire);
  55. }
  56. __forceinline void unlock() {
  57. flag.store(false,std::memory_order_release);
  58. }
  59. __forceinline void wait_until_unlocked()
  60. {
  61. while(flag.load())
  62. {
  63. _mm_pause();
  64. _mm_pause();
  65. }
  66. }
  67. public:
  68. atomic<bool> flag;
  69. };
  70. /*! safe mutex lock and unlock helper */
  71. template<typename Mutex> class Lock {
  72. public:
  73. Lock (Mutex& mutex) : mutex(mutex), locked(true) { mutex.lock(); }
  74. Lock (Mutex& mutex, bool locked) : mutex(mutex), locked(locked) {}
  75. ~Lock() { if (locked) mutex.unlock(); }
  76. __forceinline void lock() { assert(!locked); locked = true; mutex.lock(); }
  77. __forceinline bool isLocked() const { return locked; }
  78. protected:
  79. Mutex& mutex;
  80. bool locked;
  81. };
  82. }