#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() { PROFILE_LOCK("Try Acquire Read Lock") if (write_request_.load(std::memory_order_relaxed) == 1) { return false; } // We think we can enter the region readers_++; if (write_request_.load() == 1) { // Whoops, the writer acquires the lock, so we back off again readers_--; return false; } return true; } void swmr_spin_lock::reader_unlock() { PROFILE_LOCK("Release Read Lock") readers_--; } void swmr_spin_lock::writer_lock() { PROFILE_LOCK("Acquire Write 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_.load(std::memory_order_relaxed) > 0) system_details::relax_cpu(); // Spin, not expensive as relaxed load } void swmr_spin_lock::writer_unlock() { PROFILE_LOCK("Release Write Lock") write_request_ = 0; } } } }