BsSpinLock.h 1.4 KB

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