[*] NT/Win32-only: improved AuThreading::SleepNs(qwTimeout)
This commit is contained in:
parent
f13c344249
commit
22a4d3383d
@ -14,25 +14,18 @@
|
||||
#endif
|
||||
|
||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||
#include <Time/Time.hpp>
|
||||
#include <Source/Time/Time.hpp>
|
||||
#include <Source/Threading/Primitives/SMTYield.hpp>
|
||||
#endif
|
||||
|
||||
namespace Aurora::Threading
|
||||
{
|
||||
AUKN_SYM void Sleep(AuUInt64 qwTimeout)
|
||||
{
|
||||
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||
|
||||
SleepNs(AuMSToNS<AuUInt64>(qwTimeout));
|
||||
|
||||
#elif defined(AURORA_IS_MODERNNT_DERIVED)
|
||||
|
||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||
::Sleep(qwTimeout);
|
||||
|
||||
#else
|
||||
std::atomic<bool> value = false;
|
||||
BooleanWaitable waitable(value);
|
||||
WaitFor(&waitable, qwTimeout);
|
||||
SleepNs(AuMSToNS<AuUInt64>(qwTimeout));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -41,15 +34,24 @@ namespace Aurora::Threading
|
||||
#if defined(AURORA_IS_LINUX_DERIVED) || defined(AURORA_IS_BSD_DERIVED)
|
||||
|
||||
auto qwEndTime = AuTime::SteadyClockNS() + qwTimeout;
|
||||
|
||||
if ((usleep(qwTimeout / 1000) == -1) &&
|
||||
if (auto uSleepMnSec = qwTimeout / 1000)
|
||||
{
|
||||
if ((usleep(uSleepMnSec) == -1) &&
|
||||
(errno == EINTR))
|
||||
{
|
||||
AuUInt64 qwNow;
|
||||
|
||||
while ((qwNow = AuTime::SteadyClockNS()) < qwEndTime)
|
||||
{
|
||||
usleep((qwEndTime - qwNow) / 1000);
|
||||
if (auto uSleepMnSec = (qwEndTime - qwNow) / 1000)
|
||||
{
|
||||
usleep(uSleepMnSec);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,26 +61,88 @@ namespace Aurora::Threading
|
||||
|
||||
if (pNtDelayExecution)
|
||||
{
|
||||
auto uWndTimeSteadyNS = AuTime::SteadyClockNS() + qwTimeout;
|
||||
auto uEndTimeSteadyNS = AuTime::SteadyClockNS() + qwTimeout;
|
||||
auto uEndTimeSteadyNS2 = uEndTimeSteadyNS;
|
||||
|
||||
#if defined(_AURORA_WANT_STRICT_NT_WAKEUP_TIME_NO_WALL_CLOCK_SHIFT_ALLOWED)
|
||||
auto uEndTimeWall = AuTime::CurrentClockNS() + qwTimeout;
|
||||
auto uTargetTimeNt = AuTime::ConvertTimestampNs(uEndTimeWall);
|
||||
#endif
|
||||
|
||||
Win32DropSchedulerResolution();
|
||||
#else
|
||||
if (!AuSwInfo::IsWindows8Point1OrGreater())
|
||||
{
|
||||
if (qwTimeout < 500000)
|
||||
{
|
||||
uEndTimeSteadyNS -= 10'000ull;
|
||||
|
||||
(void)YieldPollNs(true, uEndTimeSteadyNS, [=]()
|
||||
{
|
||||
return false;
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (qwTimeout < AuMSToNS<AuUInt64>(1))
|
||||
{
|
||||
uEndTimeSteadyNS -= 250'000ull;
|
||||
}
|
||||
|
||||
Win32DropSchedulerResolution();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (qwTimeout < AuMSToNS<AuUInt64>(1))
|
||||
{
|
||||
uEndTimeSteadyNS -= 100'000ull;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
AuUInt64 uNowNS {};
|
||||
while ((uNowNS = AuTime::SteadyClockNS()) < uWndTimeSteadyNS)
|
||||
while ((uNowNS = AuTime::SteadyClockNS()) < uEndTimeSteadyNS2)
|
||||
{
|
||||
LARGE_INTEGER word;
|
||||
#if defined(_AURORA_WANT_STRICT_NT_WAKEUP_TIME_NO_WALL_CLOCK_SHIFT_ALLOWED)
|
||||
word.QuadPart = uTargetTimeNt;
|
||||
#else
|
||||
word.QuadPart = -((uWndTimeSteadyNS - uNowNS) / 100ull);
|
||||
if (AuThreadPrimitives::ThrdCfg::gPlatformIsSMPProcessorOptimized)
|
||||
{
|
||||
if (uEndTimeSteadyNS2 - uNowNS <= 100000ull)
|
||||
{
|
||||
for (AU_ITERATE_N(i, 32))
|
||||
{
|
||||
AuThreadPrimitives::SMPPause();
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
AuSInt sDelta1 = uEndTimeSteadyNS - uNowNS;
|
||||
word.QuadPart = 0;
|
||||
if (sDelta1 > 0)
|
||||
{
|
||||
word.QuadPart = -(sDelta1 / 100ull);
|
||||
}
|
||||
|
||||
if (!word.QuadPart)
|
||||
{
|
||||
if (AuThreadPrimitives::ThrdCfg::gPlatformIsSMPProcessorOptimized)
|
||||
{
|
||||
for (AU_ITERATE_N(i, 32))
|
||||
{
|
||||
AuThreadPrimitives::SMPPause();
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
pNtDelayExecution(FALSE, &word);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user