BsSpinLock.h 1.2 KB

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