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