BsSpinLock.h 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. #pragma once
  2. #include <atomic>
  3. namespace BansheeEngine
  4. {
  5. /** @addtogroup Threading
  6. * @{
  7. */
  8. /**
  9. * Synchronization primitive with low overhead.
  10. *
  11. * @note
  12. * However it will actively block the thread waiting for the lock, not allowing any other work to be done, so it is
  13. * best used for short locks.
  14. */
  15. class SpinLock
  16. {
  17. public:
  18. SpinLock()
  19. {
  20. mLock.clear(std::memory_order_relaxed);
  21. }
  22. /** Lock any following operations with the spin lock, not allowing any other thread to access them. */
  23. void lock()
  24. {
  25. while(mLock.test_and_set(std::memory_order_acquire))
  26. { }
  27. }
  28. /** Release the lock and allow other threads to acquire the lock. */
  29. void unlock()
  30. {
  31. mLock.clear(std::memory_order_release);
  32. }
  33. private:
  34. std::atomic_flag mLock;
  35. };
  36. /**
  37. * Provides a safer method for locking a spin lock as the lock will get automatically locked when this objected is
  38. * created and unlocked as soon as it goes out of scope.
  39. */
  40. class ScopedSpinLock
  41. {
  42. public:
  43. ScopedSpinLock(SpinLock& spinLock)
  44. :mSpinLock(spinLock)
  45. {
  46. mSpinLock.lock();
  47. }
  48. ~ScopedSpinLock()
  49. {
  50. mSpinLock.unlock();
  51. }
  52. private:
  53. SpinLock& mSpinLock;
  54. };
  55. /** @} */
  56. }