From 4917fc47f67eb3b72ae5451c1ca479d721810d42 Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Thu, 19 Oct 2023 21:07:08 +0900 Subject: [PATCH] Don't fail on "try" fns if failed to get spinLock In SharedSpinLock: Only fail on "try" fns after spinLock was acquired and condition is not met. --- src/CXX11_shared_spin_lock.cpp | 92 ++++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 38 deletions(-) diff --git a/src/CXX11_shared_spin_lock.cpp b/src/CXX11_shared_spin_lock.cpp index a3cea8e..ced00dc 100644 --- a/src/CXX11_shared_spin_lock.cpp +++ b/src/CXX11_shared_spin_lock.cpp @@ -40,14 +40,18 @@ UDPC::LockObj UDPC::SharedSpinLock::spin_read_lock() { } UDPC::LockObj UDPC::SharedSpinLock::try_spin_read_lock() { - bool expected = false; - if (spinLock.compare_exchange_weak(expected, true, std::memory_order_acquire, std::memory_order_relaxed)) { - if (!write) { - ++read; - spinLock.store(false, std::memory_order_release); - return LockObj(selfWeakPtr, Badge{}); - } else { - spinLock.store(false, std::memory_order_release); + bool expected; + while (true) { + expected = false; + if (spinLock.compare_exchange_weak(expected, true, std::memory_order_acquire, std::memory_order_relaxed)) { + if (!write) { + ++read; + spinLock.store(false, std::memory_order_release); + return LockObj(selfWeakPtr, Badge{}); + } else { + spinLock.store(false, std::memory_order_release); + break; + } } } return LockObj{}; @@ -87,14 +91,18 @@ UDPC::LockObj UDPC::SharedSpinLock::spin_write_lock() { } UDPC::LockObj UDPC::SharedSpinLock::try_spin_write_lock() { - bool expected = false; - if (spinLock.compare_exchange_weak(expected, true, std::memory_order_acquire, std::memory_order_relaxed)) { - if (!write && read == 0) { - write = true; - spinLock.store(false, std::memory_order_release); - return LockObj(selfWeakPtr, Badge{}); - } else { - spinLock.store(false, std::memory_order_release); + bool expected; + while (true) { + expected = false; + if (spinLock.compare_exchange_weak(expected, true, std::memory_order_acquire, std::memory_order_relaxed)) { + if (!write && read == 0) { + write = true; + spinLock.store(false, std::memory_order_release); + return LockObj(selfWeakPtr, Badge{}); + } else { + spinLock.store(false, std::memory_order_release); + break; + } } } return LockObj{}; @@ -142,17 +150,21 @@ UDPC::LockObj UDPC::SharedSpinLock::trade_write_for_read_lock(UDPC::LockO UDPC::LockObj UDPC::SharedSpinLock::try_trade_write_for_read_lock(UDPC::LockObj &lockObj) { if (lockObj.isValid() && lockObj.badge.isValid) { - bool expected = false; - if (spinLock.compare_exchange_weak(expected, true, std::memory_order_acquire, std::memory_order_relaxed)) { - if (write && read == 0) { - read = 1; - write = false; - lockObj.isLocked = false; - lockObj.badge.isValid = false; - spinLock.store(false, std::memory_order_release); - return LockObj(selfWeakPtr, Badge{}); - } else { - spinLock.store(false, std::memory_order_release); + bool expected; + while (true) { + expected = false; + if (spinLock.compare_exchange_weak(expected, true, std::memory_order_acquire, std::memory_order_relaxed)) { + if (write && read == 0) { + read = 1; + write = false; + lockObj.isLocked = false; + lockObj.badge.isValid = false; + spinLock.store(false, std::memory_order_release); + return LockObj(selfWeakPtr, Badge{}); + } else { + spinLock.store(false, std::memory_order_release); + break; + } } } } @@ -184,17 +196,21 @@ UDPC::LockObj UDPC::SharedSpinLock::trade_read_for_write_lock(UDPC::LockOb UDPC::LockObj UDPC::SharedSpinLock::try_trade_read_for_write_lock(UDPC::LockObj &lockObj) { if (lockObj.isValid() && lockObj.badge.isValid) { - bool expected = false; - if (spinLock.compare_exchange_weak(expected, true, std::memory_order_acquire, std::memory_order_relaxed)) { - if (!write && read == 1) { - read = 0; - write = true; - lockObj.isLocked = false; - lockObj.badge.isValid = false; - spinLock.store(false, std::memory_order_release); - return LockObj(selfWeakPtr, Badge{}); - } else { - spinLock.store(false, std::memory_order_release); + bool expected; + while (true) { + expected = false; + if (spinLock.compare_exchange_weak(expected, true, std::memory_order_acquire, std::memory_order_relaxed)) { + if (!write && read == 1) { + read = 0; + write = true; + lockObj.isLocked = false; + lockObj.badge.isValid = false; + spinLock.store(false, std::memory_order_release); + return LockObj(selfWeakPtr, Badge{}); + } else { + spinLock.store(false, std::memory_order_release); + break; + } } } }