#include "pls/internal/base/swmr_spin_lock.h" #include "pls/internal/base/system_details.h" namespace pls { namespace internal { namespace base { bool swmr_spin_lock::reader_try_lock() { if (write_request_.load(std::memory_order_acquire) == 1) { return false; } // We think we can enter the region readers_.fetch_add(1, std::memory_order_acquire); if (write_request_.load(std::memory_order_acquire) == 1) { // Whoops, the writer acquires the lock, so we back off again readers_.fetch_add(-1, std::memory_order_release); return false; } return true; } void swmr_spin_lock::reader_unlock() { readers_--; } void swmr_spin_lock::writer_lock() { // Tell the readers that we would like to write write_request_ = 1; // Wait for all of them to exit the critical section while (readers_ > 0) system_details::relax_cpu(); // Spin, not expensive as relaxed load } void swmr_spin_lock::writer_unlock() { write_request_ = 0; } } } }