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.
This commit is contained in:
Stephen Seo 2023-10-19 21:07:08 +09:00
parent a0f8bf0b41
commit 4917fc47f6

View file

@ -40,14 +40,18 @@ UDPC::LockObj<false> UDPC::SharedSpinLock::spin_read_lock() {
} }
UDPC::LockObj<false> UDPC::SharedSpinLock::try_spin_read_lock() { UDPC::LockObj<false> UDPC::SharedSpinLock::try_spin_read_lock() {
bool expected = false; bool expected;
if (spinLock.compare_exchange_weak(expected, true, std::memory_order_acquire, std::memory_order_relaxed)) { while (true) {
if (!write) { expected = false;
++read; if (spinLock.compare_exchange_weak(expected, true, std::memory_order_acquire, std::memory_order_relaxed)) {
spinLock.store(false, std::memory_order_release); if (!write) {
return LockObj<false>(selfWeakPtr, Badge{}); ++read;
} else { spinLock.store(false, std::memory_order_release);
spinLock.store(false, std::memory_order_release); return LockObj<false>(selfWeakPtr, Badge{});
} else {
spinLock.store(false, std::memory_order_release);
break;
}
} }
} }
return LockObj<false>{}; return LockObj<false>{};
@ -87,14 +91,18 @@ UDPC::LockObj<true> UDPC::SharedSpinLock::spin_write_lock() {
} }
UDPC::LockObj<true> UDPC::SharedSpinLock::try_spin_write_lock() { UDPC::LockObj<true> UDPC::SharedSpinLock::try_spin_write_lock() {
bool expected = false; bool expected;
if (spinLock.compare_exchange_weak(expected, true, std::memory_order_acquire, std::memory_order_relaxed)) { while (true) {
if (!write && read == 0) { expected = false;
write = true; if (spinLock.compare_exchange_weak(expected, true, std::memory_order_acquire, std::memory_order_relaxed)) {
spinLock.store(false, std::memory_order_release); if (!write && read == 0) {
return LockObj<true>(selfWeakPtr, Badge{}); write = true;
} else { spinLock.store(false, std::memory_order_release);
spinLock.store(false, std::memory_order_release); return LockObj<true>(selfWeakPtr, Badge{});
} else {
spinLock.store(false, std::memory_order_release);
break;
}
} }
} }
return LockObj<true>{}; return LockObj<true>{};
@ -142,17 +150,21 @@ UDPC::LockObj<false> UDPC::SharedSpinLock::trade_write_for_read_lock(UDPC::LockO
UDPC::LockObj<false> UDPC::SharedSpinLock::try_trade_write_for_read_lock(UDPC::LockObj<true> &lockObj) { UDPC::LockObj<false> UDPC::SharedSpinLock::try_trade_write_for_read_lock(UDPC::LockObj<true> &lockObj) {
if (lockObj.isValid() && lockObj.badge.isValid) { if (lockObj.isValid() && lockObj.badge.isValid) {
bool expected = false; bool expected;
if (spinLock.compare_exchange_weak(expected, true, std::memory_order_acquire, std::memory_order_relaxed)) { while (true) {
if (write && read == 0) { expected = false;
read = 1; if (spinLock.compare_exchange_weak(expected, true, std::memory_order_acquire, std::memory_order_relaxed)) {
write = false; if (write && read == 0) {
lockObj.isLocked = false; read = 1;
lockObj.badge.isValid = false; write = false;
spinLock.store(false, std::memory_order_release); lockObj.isLocked = false;
return LockObj<false>(selfWeakPtr, Badge{}); lockObj.badge.isValid = false;
} else { spinLock.store(false, std::memory_order_release);
spinLock.store(false, std::memory_order_release); return LockObj<false>(selfWeakPtr, Badge{});
} else {
spinLock.store(false, std::memory_order_release);
break;
}
} }
} }
} }
@ -184,17 +196,21 @@ UDPC::LockObj<true> UDPC::SharedSpinLock::trade_read_for_write_lock(UDPC::LockOb
UDPC::LockObj<true> UDPC::SharedSpinLock::try_trade_read_for_write_lock(UDPC::LockObj<false> &lockObj) { UDPC::LockObj<true> UDPC::SharedSpinLock::try_trade_read_for_write_lock(UDPC::LockObj<false> &lockObj) {
if (lockObj.isValid() && lockObj.badge.isValid) { if (lockObj.isValid() && lockObj.badge.isValid) {
bool expected = false; bool expected;
if (spinLock.compare_exchange_weak(expected, true, std::memory_order_acquire, std::memory_order_relaxed)) { while (true) {
if (!write && read == 1) { expected = false;
read = 0; if (spinLock.compare_exchange_weak(expected, true, std::memory_order_acquire, std::memory_order_relaxed)) {
write = true; if (!write && read == 1) {
lockObj.isLocked = false; read = 0;
lockObj.badge.isValid = false; write = true;
spinLock.store(false, std::memory_order_release); lockObj.isLocked = false;
return LockObj<true>(selfWeakPtr, Badge{}); lockObj.badge.isValid = false;
} else { spinLock.store(false, std::memory_order_release);
spinLock.store(false, std::memory_order_release); return LockObj<true>(selfWeakPtr, Badge{});
} else {
spinLock.store(false, std::memory_order_release);
break;
}
} }
} }
} }