[WINMM] Improve implementation of timeGetTime, timeBeginPeriod, timeEndPeriod (#2933)

Use QueryPerformanceCounter if a high-resolution timer is requested (<= 5ms) instead of the more inaccurate GetTickCount.
This commit is contained in:
Thomas Brogan 2020-06-20 13:28:25 +03:00 committed by GitHub
parent 2b9941e7cb
commit 88300ec3b3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -47,6 +47,7 @@ static LPWINE_TIMERENTRY TIME_TimersList;
static HANDLE TIME_hKillEvent;
static HANDLE TIME_hWakeEvent;
static BOOL TIME_TimeToDie = TRUE;
static LARGE_INTEGER TIME_qpcFreq;
/*
* Some observations on the behavior of winmm on Windows.
@ -422,7 +423,14 @@ MMRESULT WINAPI timeGetDevCaps(LPTIMECAPS lpCaps, UINT wSize)
MMRESULT WINAPI timeBeginPeriod(UINT wPeriod)
{
if (wPeriod < MMSYSTIME_MININTERVAL || wPeriod > MMSYSTIME_MAXINTERVAL)
return TIMERR_NOCANDO;
return TIMERR_NOCANDO;
/* High resolution timer requested, use QPC */
if (wPeriod <= 5 && TIME_qpcFreq.QuadPart == 0)
{
if (QueryPerformanceFrequency(&TIME_qpcFreq))
TIME_qpcFreq.QuadPart /= 1000;
}
if (wPeriod > MMSYSTIME_MININTERVAL)
{
@ -438,7 +446,11 @@ MMRESULT WINAPI timeBeginPeriod(UINT wPeriod)
MMRESULT WINAPI timeEndPeriod(UINT wPeriod)
{
if (wPeriod < MMSYSTIME_MININTERVAL || wPeriod > MMSYSTIME_MAXINTERVAL)
return TIMERR_NOCANDO;
return TIMERR_NOCANDO;
/* High resolution timer no longer requested, stop using QPC */
if (wPeriod <= 5 && TIME_qpcFreq.QuadPart != 0)
TIME_qpcFreq.QuadPart = 0;
if (wPeriod > MMSYSTIME_MININTERVAL)
{
@ -453,6 +465,7 @@ MMRESULT WINAPI timeEndPeriod(UINT wPeriod)
*/
DWORD WINAPI timeGetTime(void)
{
LARGE_INTEGER perfCount;
#if defined(COMMENTOUTPRIORTODELETING)
DWORD count;
@ -462,6 +475,12 @@ DWORD WINAPI timeGetTime(void)
if (pFnReleaseThunkLock) pFnReleaseThunkLock(&count);
if (pFnRestoreThunkLock) pFnRestoreThunkLock(count);
#endif
/* Use QPC if a high-resolution timer was requested (<= 5ms) */
if (TIME_qpcFreq.QuadPart != 0)
{
QueryPerformanceCounter(&perfCount);
return (DWORD)(perfCount.QuadPart / TIME_qpcFreq.QuadPart);
}
/* Otherwise continue using GetTickCount */
return GetTickCount();
}