#include "CXX11_shared_spin_lock.hpp" UDPC::Badge UDPC::Badge::newInvalid() { Badge badge; badge.isValid = false; return badge; } UDPC::Badge::Badge() : isValid(true) {} UDPC::SharedSpinLock::Ptr UDPC::SharedSpinLock::newInstance() { Ptr sharedSpinLock = Ptr(new SharedSpinLock()); sharedSpinLock->selfWeakPtr = sharedSpinLock; return sharedSpinLock; } UDPC::SharedSpinLock::SharedSpinLock() : selfWeakPtr(), mutex(), read(0), write(false) {} UDPC::LockObj UDPC::SharedSpinLock::spin_read_lock() { while (true) { std::lock_guard lock(mutex); if (!write) { ++read; return LockObj(selfWeakPtr, Badge{}); } } } UDPC::LockObj UDPC::SharedSpinLock::try_spin_read_lock() { std::lock_guard lock(mutex); if (!write) { ++read; return LockObj(selfWeakPtr, Badge{}); } return LockObj(Badge{}); } void UDPC::SharedSpinLock::read_unlock(UDPC::Badge &&badge) { if (badge.isValid) { std::lock_guard lock(mutex); if (read > 0) { --read; badge.isValid = false; } } } UDPC::LockObj UDPC::SharedSpinLock::spin_write_lock() { while (true) { std::lock_guard lock(mutex); if (!write && read == 0) { write = true; return LockObj(selfWeakPtr, Badge{}); } } } UDPC::LockObj UDPC::SharedSpinLock::try_spin_write_lock() { std::lock_guard lock(mutex); if (!write && read == 0) { write = true; return LockObj(selfWeakPtr, Badge{}); } return LockObj(Badge{}); } void UDPC::SharedSpinLock::write_unlock(UDPC::Badge &&badge) { if (badge.isValid) { std::lock_guard lock(mutex); write = false; badge.isValid = false; } } UDPC::LockObj UDPC::SharedSpinLock::trade_write_for_read_lock(UDPC::LockObj &lockObj) { if (lockObj.isValid() && lockObj.badge.isValid) { while (true) { std::lock_guard lock(mutex); if (write && read == 0) { read = 1; write = false; lockObj.isLocked = false; lockObj.badge.isValid = false; return LockObj(selfWeakPtr, Badge{}); } } } else { return LockObj(Badge{}); } } UDPC::LockObj UDPC::SharedSpinLock::try_trade_write_for_read_lock(UDPC::LockObj &lockObj) { if (lockObj.isValid() && lockObj.badge.isValid) { std::lock_guard lock(mutex); if (write && read == 0) { read = 1; write = false; lockObj.isLocked = false; lockObj.badge.isValid = false; return LockObj(selfWeakPtr, Badge{}); } } return LockObj(Badge{}); } UDPC::LockObj UDPC::SharedSpinLock::trade_read_for_write_lock(UDPC::LockObj &lockObj) { if (lockObj.isValid() && lockObj.badge.isValid) { while (true) { std::lock_guard lock(mutex); if (!write && read == 1) { read = 0; write = true; lockObj.isLocked = false; lockObj.badge.isValid = false; return LockObj(selfWeakPtr, Badge{}); } } } else { return LockObj(Badge{}); } } UDPC::LockObj UDPC::SharedSpinLock::try_trade_read_for_write_lock(UDPC::LockObj &lockObj) { if (lockObj.isValid() && lockObj.badge.isValid) { std::lock_guard lock(mutex); if (!write && read == 1) { read = 0; write = true; lockObj.isLocked = false; lockObj.badge.isValid = false; return LockObj(selfWeakPtr, Badge{}); } } return LockObj(Badge{}); }