[*] Developers developers developers developers

Absolute expiration times track any changes in the system time; relative expiration times are not affected by system time changes.
This commit is contained in:
Reece Wilson 2024-04-23 23:17:40 +01:00
parent 0a90fd1a25
commit 44c7898c29
3 changed files with 49 additions and 13 deletions

View File

@ -59,16 +59,27 @@ namespace Aurora::Threading
if (pNtDelayExecution) if (pNtDelayExecution)
{ {
auto endTimeSteady = AuTime::SteadyClockNS() + qwTimeout; auto uWndTimeSteadyNS = AuTime::SteadyClockNS() + qwTimeout;
auto endTimeWall = AuTime::CurrentClockNS() + qwTimeout; #if defined(_AURORA_WANT_STRICT_NT_WAKEUP_TIME_NO_WALL_CLOCK_SHIFT_ALLOWED)
auto targetTimeNt = AuTime::ConvertTimestampNs(endTimeWall); auto uEndTimeWall = AuTime::CurrentClockNS() + qwTimeout;
auto uTargetTimeNt = AuTime::ConvertTimestampNs(uEndTimeWall);
#endif
Win32DropSchedulerResolution(); Win32DropSchedulerResolution();
while (AuTime::SteadyClockNS() < endTimeSteady) AuUInt64 uNowNS {};
while ((uNowNS = AuTime::SteadyClockNS()) < uWndTimeSteadyNS)
{ {
LARGE_INTEGER word; LARGE_INTEGER word;
word.QuadPart = targetTimeNt; #if defined(_AURORA_WANT_STRICT_NT_WAKEUP_TIME_NO_WALL_CLOCK_SHIFT_ALLOWED)
word.QuadPart = uTargetTimeNt;
#else
word.QuadPart = -((uWndTimeSteadyNS - uNowNS) / 100ull);
if (!word.QuadPart)
{
break;
}
#endif
pNtDelayExecution(FALSE, &word); pNtDelayExecution(FALSE, &word);
} }

View File

@ -55,15 +55,16 @@ namespace Aurora::Threading::Primitives
if (qwTimeout) if (qwTimeout)
{ {
#if defined(_AURORA_WANT_STRICT_NT_WAKEUP_TIME_NO_WALL_CLOCK_SHIFT_ALLOWED)
auto uEndTimeSteady = gUseNativeWaitCondvar ? AuTime::SteadyClockNS() + qwTimeout : 0; auto uEndTimeSteady = gUseNativeWaitCondvar ? AuTime::SteadyClockNS() + qwTimeout : 0;
auto uEndTimeWall = AuTime::CurrentClockNS() + qwTimeout; auto uEndTimeWall = AuTime::CurrentClockNS() + qwTimeout;
auto uTargetTimeNt = AuTime::ConvertTimestampNs(uEndTimeWall); auto uTargetTimeNt = AuTime::ConvertTimestampNs(uEndTimeWall);
#else
auto uEndTimeSteady = AuTime::SteadyClockNS() + qwTimeout;
#endif
while (true) while (true)
{ {
LARGE_INTEGER word;
word.QuadPart = uTargetTimeNt;
if (bRet) if (bRet)
{ {
if (gUseNativeWaitCondvar) if (gUseNativeWaitCondvar)
@ -99,7 +100,25 @@ namespace Aurora::Threading::Primitives
} }
} }
bRet = pNtWaitForKeyedEvent(gKeyedEventHandle, (void *)&this->wlist, 0, &word) == 0; {
LARGE_INTEGER word;
#if defined(_AURORA_WANT_STRICT_NT_WAKEUP_TIME_NO_WALL_CLOCK_SHIFT_ALLOWED)
word.QuadPart = uTargetTimeNt;
#else
auto uNow = AuTime::SteadyClockNS();
if (uEndTimeSteady > uNow)
{
word.QuadPart = -((uEndTimeSteady - uNow) / 100ull);
}
else
{
word.QuadPart = 0;
}
#endif
bRet = pNtWaitForKeyedEvent(gKeyedEventHandle, (void *)&this->wlist, 0, &word) == 0;
}
} }
} }
else /* unblock NtReleaseKeyedEvent after an atomic this->wlist change <-> NtReleaseKeyedEvent race condition. */ else /* unblock NtReleaseKeyedEvent after an atomic this->wlist change <-> NtReleaseKeyedEvent race condition. */

View File

@ -183,15 +183,18 @@ namespace Aurora::Threading::Primitives
returnValue = true; returnValue = true;
auto uEndTimeSteady = AuTime::SteadyClockNS() + uTimeout; auto uEndTimeSteady = AuTime::SteadyClockNS() + uTimeout;
#if defined(_AURORA_WANT_STRICT_NT_WAKEUP_TIME_NO_WALL_CLOCK_SHIFT_ALLOWED)
auto uEndTimeWall = AuTime::CurrentClockNS() + uTimeout; auto uEndTimeWall = AuTime::CurrentClockNS() + uTimeout;
#endif
bool bFailed {}; bool bFailed {};
while (bFailed || (!this->TryLockNoSpin())) while (bFailed || (!this->TryLockNoSpin()))
{ {
auto uValue = uValueRef | 1; auto uValue = uValueRef | 1;
AuUInt64 uNowNS {};
if (!bFailed && if ((!bFailed) &&
AuTime::SteadyClockNS() >= uEndTimeSteady) ((uNowNS = AuTime::SteadyClockNS()) >= uEndTimeSteady))
{ {
returnValue = this->TryLock(); returnValue = this->TryLock();
break; break;
@ -199,10 +202,13 @@ namespace Aurora::Threading::Primitives
if (bFailed || AuAtomicCompareExchange(&uValueRef, uValue + kFutexBitWait, uValue) == uValue) if (bFailed || AuAtomicCompareExchange(&uValueRef, uValue + kFutexBitWait, uValue) == uValue)
{ {
auto uTargetTimeNt = AuTime::ConvertTimestampNs(uEndTimeWall);
LARGE_INTEGER word; LARGE_INTEGER word;
word.QuadPart = uTargetTimeNt; #if defined(_AURORA_WANT_STRICT_NT_WAKEUP_TIME_NO_WALL_CLOCK_SHIFT_ALLOWED)
word.QuadPart = AuTime::ConvertTimestampNs(uEndTimeWall);
#else
word.QuadPart = -((uEndTimeSteady - uNowNS) / 100ull);
#endif
auto uStatus = pNtWaitForKeyedEvent(gKeyedEventHandle, (void *)&this->state_, 0, &word); auto uStatus = pNtWaitForKeyedEvent(gKeyedEventHandle, (void *)&this->state_, 0, &word);
if (uStatus == NTSTATUS_TIMEOUT) if (uStatus == NTSTATUS_TIMEOUT)