https://git.reactos.org/?p=reactos.git;a=commitdiff;h=88300ec3b3bbb2fc024f1d...
commit 88300ec3b3bbb2fc024f1d960d317dd802c4a3f6 Author: Thomas Brogan brogan.tom.iii@gmail.com AuthorDate: Sat Jun 20 13:28:25 2020 +0300 Commit: GitHub noreply@github.com CommitDate: Sat Jun 20 13:28:25 2020 +0300
[WINMM] Improve implementation of timeGetTime, timeBeginPeriod, timeEndPeriod (#2933)
Use QueryPerformanceCounter if a high-resolution timer is requested (<= 5ms) instead of the more inaccurate GetTickCount. --- dll/win32/winmm/time.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/dll/win32/winmm/time.c b/dll/win32/winmm/time.c index 5da3f2f0752..832a45ba4fa 100644 --- a/dll/win32/winmm/time.c +++ b/dll/win32/winmm/time.c @@ -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(); }