https://git.reactos.org/?p=reactos.git;a=commitdiff;h=88300ec3b3bbb2fc024f1…
commit 88300ec3b3bbb2fc024f1d960d317dd802c4a3f6
Author: Thomas Brogan <brogan.tom.iii(a)gmail.com>
AuthorDate: Sat Jun 20 13:28:25 2020 +0300
Commit: GitHub <noreply(a)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();
}