#pragma once #include #include "common.hpp" #include "utils/mixins.hpp" LEMONBUDDY_NS namespace threading_util { namespace locking_strategy { struct no_backoff { bool operator()() { return true; } }; struct yield_backoff { bool operator()() { this_thread::yield(); return false; } }; } class spin_lock : public non_copyable_mixin { public: /** * Construct spin_lock */ spin_lock() = default; /** * Lock using custom strategy */ template void lock(Backoff backoff) noexcept { while (m_locked.test_and_set(std::memory_order_acquire)) { backoff(); } } /** * Lock using default strategy */ void lock() noexcept { lock(locking_strategy::no_backoff{}); } /** * Unlock */ void unlock() noexcept { m_locked.clear(std::memory_order_release); } protected: std::atomic_flag m_locked{false}; }; } LEMONBUDDY_NS_END