/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: AuSpinLock.cpp Date: 2021-6-12 Author: Reece ***/ #include #include "AuSpinLock.hpp" #include "SMTYield.hpp" namespace Aurora::Threading::Primitives { SpinLock::SpinLock() { this->state_ = 0; } bool SpinLock::HasOSHandle(AuMach &mach) { return false; } bool SpinLock::TryLock() { return DoTryIfAlderLake([=]() { return AuAtomicTestAndSet(&this->state_, 0) == 0; }, &this->state_); } bool SpinLock::HasLockImplementation() { return true; } void SpinLock::SlowLock() { auto status = LockNS(0); SysAssert(status, "Couldn't lock Mutex object"); } bool SpinLock::LockAbsNS(AuUInt64 timeout) { if (timeout == 0) { while (true) { if (DoTryIfAlderLake([=]() { return AuAtomicTestAndSet(&this->state_, 0) == 0; }, &this->state_)) { return true; } } } else { while (AuAtomicTestAndSet(&this->state_, 0)) { if (DoTryIfAlderLake([=]() { return AuAtomicTestAndSet(&this->state_, 0) == 0; }, &this->state_)) { return true; } if (timeout <= AuTime::SteadyClockNS()) { return false; } } return true; } return true; } bool SpinLock::LockNS(AuUInt64 timeout) { if (timeout == 0) { while (true) { if (DoTryIfAlderLake([=]() { return AuAtomicTestAndSet(&this->state_, 0) == 0; }, &this->state_)) { return true; } } } else { timeout += AuTime::SteadyClockNS(); while (AuAtomicTestAndSet(&this->state_, 0)) { if (DoTryIfAlderLake([=]() { return AuAtomicTestAndSet(&this->state_, 0) == 0; }, &this->state_)) { return true; } if (timeout <= AuTime::SteadyClockNS()) { return false; } } return true; } return true; } bool SpinLock::LockMS(AuUInt64 timeout) { return LockNS(AuMSToNS(timeout)); } void SpinLock::Unlock() { this->state_ = 0; } }