Increase accuracy of Windows Sleep function

Windows 10 version 1803 (build 17134) and later versions support
high-resolution waitable timer, which offers much better accuracy over
Sleep function without the need of increasing the global timer
resolution. For older versions of Windows, we reduce the timer
resolution to 1ms and use normal waitable timer for sleeping.
This commit is contained in:
GoaLitiuM
2021-05-29 19:46:37 +03:00
parent c01a140077
commit cc60814334
2 changed files with 22 additions and 1 deletions

View File

@@ -456,7 +456,21 @@ void Win32Platform::SetThreadAffinityMask(uint64 affinityMask)
void Win32Platform::Sleep(int32 milliseconds)
{
::Sleep(static_cast<DWORD>(milliseconds));
static thread_local HANDLE timer = NULL;
if (timer == NULL)
{
// Attempt to create high-resolution timer for each thread (Windows 10 build 17134 or later)
timer = CreateWaitableTimerEx(NULL, NULL, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS);
if (timer == NULL) // fallback for older versions of Windows
timer = CreateWaitableTimer(NULL, TRUE, NULL);
}
// Negative value is relative to current time, minimum waitable time is 10 microseconds
LARGE_INTEGER dueTime;
dueTime.QuadPart = -int64_t(milliseconds) * 10000;
SetWaitableTimerEx(timer, &dueTime, 0, NULL, NULL, NULL, 0);
WaitForSingleObject(timer, INFINITE);
}
double Win32Platform::GetTimeSeconds()

View File

@@ -18,6 +18,7 @@
#include "../Win32/IncludeWindowsHeaders.h"
#include <VersionHelpers.h>
#include <ShellAPI.h>
#include <timeapi.h>
#include <Psapi.h>
#include <objbase.h>
#if CRASH_LOG_ENABLE
@@ -579,6 +580,12 @@ bool WindowsPlatform::Init()
return true;
}
// Set lowest possible timer resolution for previous Windows versions
if (VersionMajor < 10 || (VersionMajor == 10 && VersionBuild < 17134))
{
timeBeginPeriod(1);
}
DWORD tmp;
Char buffer[256];