/** * @file libipc/spin_lock.h * @author mutouyun (orz@orzz.org) * @brief Define spin locks * @date 2022-02-27 */ #pragma once #include #include #include #include #include "libimp/export.h" #include "libipc/def.h" LIBIPC_NAMESPACE_BEG_ /** * @brief Gives hint to processor that improves performance of spin-wait loops. */ LIBIMP_EXPORT void pause() noexcept; /** * @brief Yield to other threads */ template inline void yield(K &k) noexcept { if (k < 4) { /* Do nothing */ } else if (k < 16) { pause(); } else if (k < 32) { std::this_thread::yield(); } else { std::this_thread::sleep_for(std::chrono::microseconds(1)); return; } ++k; } template inline void sleep(K &k, F &&f) { if (k < static_cast(N)) { std::this_thread::yield(); } else { static_cast(std::forward(f)()); return; } ++k; } template inline void sleep(K &k) { sleep(k, [] { std::this_thread::sleep_for(std::chrono::microseconds(1)); }); } /** * @brief Basic spin lock */ class LIBIMP_EXPORT spin_lock { std::atomic lc_ {0}; public: void lock() noexcept; void unlock() noexcept; }; /** * @brief Support for shared mode spin lock */ class LIBIMP_EXPORT rw_lock { std::atomic lc_ {0}; public: void lock() noexcept; void unlock() noexcept; void lock_shared() noexcept; void unlock_shared() noexcept; }; LIBIPC_NAMESPACE_END_