DSPark 1.6.1
Header-only audio DSP framework in pure C++20 — zero dependencies
Loading...
Searching...
No Matches
SpinLock.h
Go to the documentation of this file.
1// DSPark -- Professional Audio DSP Framework
2// Copyright (c) 2026 Cristian Moresi -- MIT License
3
4#pragma once
5
38#include <atomic>
39
40#if (defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86))) \
41 || defined(__x86_64__) || defined(__i386__) || defined(__SSE2__)
42 // x86 / x86-64 (any compiler): PAUSE spin hint.
43 #include <immintrin.h>
44 #define DSPARK_SPIN_PAUSE() _mm_pause()
45#elif defined(_MSC_VER) && defined(_M_ARM64)
46 // MSVC on ARM64: _mm_pause() does not exist here; use the YIELD intrinsic.
47 #include <intrin.h>
48 #define DSPARK_SPIN_PAUSE() __yield()
49#elif defined(__aarch64__) || defined(__arm__) || defined(__ARM_NEON)
50 // GCC/Clang on ARM: YIELD instruction.
51 #define DSPARK_SPIN_PAUSE() __asm__ __volatile__("yield")
52#else
53 // WebAssembly / unknown: safe no-op.
54 #define DSPARK_SPIN_PAUSE() ((void)0)
55#endif
56
57namespace dspark {
58
70{
71public:
73 SpinLock() noexcept = default;
74
75 SpinLock(const SpinLock&) = delete;
76 SpinLock& operator=(const SpinLock&) = delete;
77
88 void lock() noexcept
89 {
90 for (;;)
91 {
92 // Attempt to grab the lock
93 if (!flag_.test_and_set(std::memory_order_acquire)) {
94 return;
95 }
96
97 // Spin on a relaxed read to prevent cache line bouncing
98 while (flag_.test(std::memory_order_relaxed)) {
99 DSPARK_SPIN_PAUSE(); // Hint CPU to yield resources during spin
100 }
101 }
102 }
103
108 [[nodiscard]] bool tryLock() noexcept
109 {
110 return !flag_.test_and_set(std::memory_order_acquire);
111 }
112
119 [[nodiscard]] bool try_lock() noexcept { return tryLock(); }
120
124 void unlock() noexcept
125 {
126 flag_.clear(std::memory_order_release);
127 }
128
129 // ========================================================================
130
136 {
137 public:
142 explicit ScopedLock(SpinLock& spinLock) noexcept : lock_(spinLock) { lock_.lock(); }
143
145 ~ScopedLock() noexcept { lock_.unlock(); }
146
147 ScopedLock(const ScopedLock&) = delete;
148 ScopedLock& operator=(const ScopedLock&) = delete;
149
150 private:
151 SpinLock& lock_;
152 };
153
162 {
163 public:
168 explicit ScopedTryLock(SpinLock& spinLock) noexcept
169 : lock_(spinLock), acquired_(spinLock.tryLock()) {}
170
172 ~ScopedTryLock() noexcept { if (acquired_) lock_.unlock(); }
173
178 [[nodiscard]] bool isLocked() const noexcept { return acquired_; }
179
180 ScopedTryLock(const ScopedTryLock&) = delete;
182
183 private:
184 SpinLock& lock_;
185 bool acquired_;
186 };
187
188private:
189 // C++20 default initialization correctly sets the atomic_flag to the clear state.
190 // ATOMIC_FLAG_INIT is deprecated in C++20 and removed in C++26.
191 std::atomic_flag flag_{};
192};
193
194} // namespace dspark
#define DSPARK_SPIN_PAUSE()
Definition SpinLock.h:54
RAII wrapper that acquires the lock on construction and releases on destruction.
Definition SpinLock.h:136
~ScopedLock() noexcept
Destructs the guard and releases the lock.
Definition SpinLock.h:145
ScopedLock & operator=(const ScopedLock &)=delete
ScopedLock(SpinLock &spinLock) noexcept
Constructs the guard and blocks until the lock is acquired.
Definition SpinLock.h:142
ScopedLock(const ScopedLock &)=delete
RAII wrapper that tries to acquire the lock without blocking.
Definition SpinLock.h:162
ScopedTryLock & operator=(const ScopedTryLock &)=delete
~ScopedTryLock() noexcept
Destructs the guard and releases the lock ONLY if it was successfully acquired.
Definition SpinLock.h:172
ScopedTryLock(const ScopedTryLock &)=delete
bool isLocked() const noexcept
Queries whether the lock acquisition was successful.
Definition SpinLock.h:178
ScopedTryLock(SpinLock &spinLock) noexcept
Constructs the guard and attempts a single lock acquisition.
Definition SpinLock.h:168
A minimal, real-time safe spin lock with a TTAS wait loop.
Definition SpinLock.h:70
bool tryLock() noexcept
Attempts to acquire the lock without waiting.
Definition SpinLock.h:108
void unlock() noexcept
Releases the lock, restoring it to the clear state.
Definition SpinLock.h:124
SpinLock() noexcept=default
Constructs an unlocked SpinLock.
bool try_lock() noexcept
Standard-library spelling of tryLock().
Definition SpinLock.h:119
void lock() noexcept
Acquires the lock, spinning until successful.
Definition SpinLock.h:88
Main namespace for the DSPark framework.