/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: IWaitable.hpp Date: 2021-6-10 Author: Reece ***/ #pragma once namespace Aurora::Time { AUKN_SYM AuUInt64 SteadyClockNS(); AUKN_SYM AuUInt64 SteadyClockMS(); } namespace Aurora::Threading { /** IWaitable represents a generic waitable primitive
There is no guarantee of any specific underlying primitive or backing by the operating system directly
*All* methods **must** be supported on all platforms.
*/ struct AUKN_SYM IWaitable { // Mostly worthless. Do not access // Used by internals virtual bool HasOSHandle(AuMach &mach) = 0; // Do not access // Used by internals virtual bool HasLockImplementation() = 0; virtual void Lock() = 0; inline virtual bool LockMS(AuUInt64 qwRelTimeoutInMs /* = 0, infinity - use TryLock for an opportunistic lock-spin-once operation */) { return this->LockAbsNS(qwRelTimeoutInMs ? Aurora::Time::SteadyClockNS() + AuMSToNS(qwRelTimeoutInMs) : 0); } inline virtual bool LockNS(AuUInt64 qwRelTimeoutInNs /* = 0, infinity - use TryLock for an opportunistic lock-spin-once operation */) { return this->LockAbsNS(qwRelTimeoutInNs ? Aurora::Time::SteadyClockNS() + qwRelTimeoutInNs : 0); } inline virtual bool LockAbsMS(AuUInt64 qwAbsTimeoutInMs /* = 0, infinity*/) { if (!qwAbsTimeoutInMs) { return this->LockNS(0); } auto iTimeMSDelta = AuInt64(qwAbsTimeoutInMs) - AuInt64(Aurora::Time::SteadyClockMS()); if (iTimeMSDelta <= 0) { return this->TryLock(); } return this->LockAbsNS(AuMSToNS(iTimeMSDelta) + Aurora::Time::SteadyClockNS()); } inline virtual bool LockAbsNS(AuUInt64 qwAbsTimeoutInNs /* = 0, infinity*/) { if (!qwAbsTimeoutInNs) { return this->LockNS(0); } auto iTimeDelta = AuInt64(qwAbsTimeoutInNs) - AuInt64(Aurora::Time::SteadyClockNS()); if (iTimeDelta <= 0) { return this->TryLock(); } return this->LockNS(iTimeDelta); } virtual bool TryLock() = 0; virtual void Unlock() = 0; }; }