/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: SpinLock.cpp Date: 2021-6-12 Author: Reece ***/ #include #include "SpinLock.hpp" namespace Aurora::Threading::Primitives { static void YieldCpu(long &count) { int loops = (1 << count); while (loops > 0) { #if (defined(AURORA_ARCH_X64) || defined(AURORA_ARCH_X86)) _mm_pause(); #endif loops -= 1; } } SpinLock::SpinLock() { value_ = 0; } bool SpinLock::HasOSHandle(AuMach &mach) { return false; } bool SpinLock::TryLock() { #if defined(_AU_HAS_ATOMIC_INTRINS) return _interlockedbittestandset(&value_, 0) == 0; #else return value_.fetch_or(1); #endif } bool SpinLock::HasLockImplementation() { return true; } void SpinLock::Lock() { auto status = Lock(0); SysAssert(status, "Couldn't lock Mutex object"); } bool SpinLock::Lock(AuUInt64 timeout) { #if defined(_AU_HAS_ATOMIC_INTRINS) while (_interlockedbittestandset(&value_, 0)) #else while (value_.fetch_or(1)) #endif { long count = 0; while (value_) { YieldCpu(count); } } return true; } void SpinLock::Unlock() { value_ = 0; } }