quill
Spinlock.h
1 
7 #pragma once
8 
9 #include "quill/core/Attributes.h"
10 #include <atomic>
11 #include <cstdint>
12 
13 QUILL_BEGIN_NAMESPACE
14 
15 namespace detail
16 {
17 /***/
18 class Spinlock
19 {
20 public:
21  Spinlock() = default;
22 
26  Spinlock(Spinlock const&) = delete;
27  Spinlock& operator=(Spinlock const&) = delete;
28 
29  /***/
30  QUILL_ATTRIBUTE_HOT void lock() noexcept
31  {
32  do
33  {
34  while (_flag.load(std::memory_order_relaxed) == State::Locked)
35  {
36  // keep trying
37  }
38  } while (_flag.exchange(State::Locked, std::memory_order_acquire) == State::Locked);
39  }
40 
41  /***/
42  QUILL_ATTRIBUTE_HOT void unlock() noexcept
43  {
44  _flag.store(State::Free, std::memory_order_release);
45  }
46 
47 private:
48  enum class State : uint8_t
49  {
50  Free = 0,
51  Locked = 1
52  };
53 
54  std::atomic<State> _flag{State::Free};
55 };
56 
57 /***/
58 class LockGuard
59 {
60 public:
61  explicit LockGuard(Spinlock& s) : _spinlock(s) { _spinlock.lock(); }
62  ~LockGuard() { _spinlock.unlock(); }
63 
67  LockGuard(LockGuard const&) = delete;
68  LockGuard& operator=(LockGuard const&) = delete;
69 
70 private:
71  Spinlock& _spinlock;
72 };
73 } // namespace detail
74 
75 QUILL_END_NAMESPACE
Setups a signal handler to handle fatal signals.
Definition: BackendManager.h:24
Definition: Spinlock.h:18
Definition: Spinlock.h:58