[PATCH 3/3] ntdll: Improve the Nt{Query,Set}TimerResolution() stubs.

Francois Gouget fgouget at codeweavers.com
Thu Jul 29 08:05:47 CDT 2021


Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
---
This allows using them in the tests dealing with timers.
---
 dlls/kernelbase/tests/sync.c |  8 ++---
 dlls/ntdll/tests/time.c      | 60 ++++++++++++++++++------------------
 dlls/ntdll/unix/sync.c       | 33 +++++++++++++++++---
 3 files changed, 63 insertions(+), 38 deletions(-)

diff --git a/dlls/kernelbase/tests/sync.c b/dlls/kernelbase/tests/sync.c
index 54c2dfe99f5..abb0254c929 100644
--- a/dlls/kernelbase/tests/sync.c
+++ b/dlls/kernelbase/tests/sync.c
@@ -201,13 +201,13 @@ static void test_Sleep(void)
 
     cur = 156250;
     status = NtQueryTimerResolution(&dummy, &dummy, &cur);
-    todo_wine ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%x)\n", status);
+    ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%x)\n", status);
     expected_time = 100.0 * cur / 10000000.0;
 
     elapsed_time = (t2.QuadPart - t1.QuadPart) / (double)frequency.QuadPart;
-    todo_wine ok(0.9 * expected_time <= elapsed_time &&
-                 elapsed_time <= 1.5 * expected_time,
-                 "got %f, expected about %f\n", elapsed_time, expected_time);
+    ok(0.9 * expected_time <= elapsed_time &&
+       elapsed_time <= 1.5 * expected_time,
+       "got %f, expected about %f\n", elapsed_time, expected_time);
 }
 
 START_TEST(sync)
diff --git a/dlls/ntdll/tests/time.c b/dlls/ntdll/tests/time.c
index 5f9c49989d8..f75b159f441 100644
--- a/dlls/ntdll/tests/time.c
+++ b/dlls/ntdll/tests/time.c
@@ -218,16 +218,16 @@ static void test_RtlQueryPerformanceCounter(void)
 
 #define CHECK_CURRENT_TIMER(expected) \
     do { \
-        todo_wine ok(status == STATUS_SUCCESS, "NtSetTimerResolution failed %x\n", status); \
-        todo_wine ok(cur2 == (expected), "expected new timer resolution %u, got %u\n", (expected), cur2); \
+        ok(status == STATUS_SUCCESS, "NtSetTimerResolution failed %x\n", status); \
+        ok(cur2 == (expected), "expected new timer resolution %u, got %u\n", (expected), cur2); \
         min2 = min + 10; \
         cur2 = min2 + 1; \
         max2 = cur2 + 1; \
         status = NtQueryTimerResolution(&min2, &max2, &cur2); \
-        todo_wine ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed %x\n", status); \
-        todo_wine ok(min2 == min, "NtQueryTimerResolution() expected min=%u, got %u\n", min, min2); \
-        todo_wine ok(max2 == max, "NtQueryTimerResolution() expected max=%u, got %u\n", max, max2); \
-        todo_wine ok(cur2 == expected, "NtQueryTimerResolution() expected timer resolution %u, got %u\n", (expected), cur2); \
+        ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed %x\n", status); \
+        ok(min2 == min, "NtQueryTimerResolution() expected min=%u, got %u\n", min, min2); \
+        ok(max2 == max, "NtQueryTimerResolution() expected max=%u, got %u\n", max, max2); \
+        ok(cur2 == expected, "NtQueryTimerResolution() expected timer resolution %u, got %u\n", (expected), cur2); \
     } while (0)
 
 static void test_TimerResolution(void)
@@ -236,46 +236,46 @@ static void test_TimerResolution(void)
     NTSTATUS status;
 
     status = NtQueryTimerResolution(NULL, &max, &cur);
-    todo_wine ok(status == STATUS_ACCESS_VIOLATION, "NtQueryTimerResolution(NULL,,) success\n");
+    ok(status == STATUS_ACCESS_VIOLATION, "NtQueryTimerResolution(NULL,,) success\n");
 
     status = NtQueryTimerResolution(&min, NULL, &cur);
-    todo_wine ok(status == STATUS_ACCESS_VIOLATION, "NtQueryTimerResolution(,NULL,) success\n");
+    ok(status == STATUS_ACCESS_VIOLATION, "NtQueryTimerResolution(,NULL,) success\n");
 
     status = NtQueryTimerResolution(&min, &max, NULL);
-    todo_wine ok(status == STATUS_ACCESS_VIOLATION, "NtQueryTimerResolution(,,NULL) success\n");
+    ok(status == STATUS_ACCESS_VIOLATION, "NtQueryTimerResolution(,,NULL) success\n");
 
     min = 212121;
     cur = min + 1;
     max = cur + 1;
     status = NtQueryTimerResolution(&min, &max, &cur);
-    todo_wine ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%x)\n", status);
-    todo_wine ok(min == 156250 /* 1/64s HPET */ || min == 156001 /* RTC */,
-                 "unexpected minimum timer resolution %u\n", min);
+    ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%x)\n", status);
+    ok(min == 156250 /* 1/64s HPET */ || min == 156001 /* RTC */,
+       "unexpected minimum timer resolution %u\n", min);
     ok(0 < max, "invalid maximum timer resolution, should be 0 < %u\n", max);
-    todo_wine ok(max <= cur && cur <= min, "invalid timer resolutions, should be %u <= %u <= %u\n", max, cur, min);
+    ok(max <= cur && cur <= min, "invalid timer resolutions, should be %u <= %u <= %u\n", max, cur, min);
 
     status = NtSetTimerResolution(0, FALSE, NULL);
-    todo_wine ok(status == STATUS_ACCESS_VIOLATION, "NtSetTimerResolution(,,NULL) success\n");
+    ok(status == STATUS_ACCESS_VIOLATION, "NtSetTimerResolution(,,NULL) success\n");
 
     /* Nothing happens if that pointer is not good */
     status = NtSetTimerResolution(cur - 1, TRUE, NULL);
-    todo_wine ok(status == STATUS_ACCESS_VIOLATION, "NtSetTimerResolution() failed %x\n", status);
+    ok(status == STATUS_ACCESS_VIOLATION, "NtSetTimerResolution() failed %x\n", status);
 
     min2 = min + 1;
     cur2 = min2 + 1;
     max2 = cur2 + 1;
     status = NtQueryTimerResolution(&min2, &max2, &cur2);
-    todo_wine ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%x)\n", status);
-    todo_wine ok(min2 == min, "NtQueryTimerResolution() expected min=%u, got %u\n", min, min2);
-    todo_wine ok(max2 == max, "NtQueryTimerResolution() expected max=%u, got %u\n", max, max2);
-    todo_wine ok(cur2 == cur, "NtQueryTimerResolution() expected timer resolution %u, got %u\n", cur, cur2);
+    ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%x)\n", status);
+    ok(min2 == min, "NtQueryTimerResolution() expected min=%u, got %u\n", min, min2);
+    ok(max2 == max, "NtQueryTimerResolution() expected max=%u, got %u\n", max, max2);
+    ok(cur2 == cur, "NtQueryTimerResolution() expected timer resolution %u, got %u\n", cur, cur2);
 
     /* 'fails' until the first valid timer resolution request */
     cur2 = 7654321;
     status = NtSetTimerResolution(0, FALSE, &cur2);
-    todo_wine ok(status == STATUS_TIMER_RESOLUTION_NOT_SET, "NtSetTimerResolution() failed %x\n", status);
+    ok(status == STATUS_TIMER_RESOLUTION_NOT_SET, "NtSetTimerResolution() failed %x\n", status);
     /* and returns the current timer resolution */
-    todo_wine ok(cur2 == cur, "expected requested timer resolution %u, got %u\n", cur, cur2);
+    ok(cur2 == cur, "expected requested timer resolution %u, got %u\n", cur, cur2);
 
 
     cur2 = 7654321;
@@ -285,18 +285,18 @@ static void test_TimerResolution(void)
     /* Rescinds our timer resolution request */
     cur2 = 7654321;
     status = NtSetTimerResolution(0, FALSE, &cur2);
-    todo_wine ok(status == STATUS_SUCCESS, "NtSetTimerResolution() failed %x\n", status);
+    ok(status == STATUS_SUCCESS, "NtSetTimerResolution() failed %x\n", status);
     /* -> the timer resolution was reset to its initial value */
-    todo_wine ok(cur2 == cur, "expected requested timer resolution %u, got %u\n", min, cur2);
+    ok(cur2 == cur, "expected requested timer resolution %u, got %u\n", min, cur2);
 
     cur2 = 7654321;
     status = NtSetTimerResolution(0, FALSE, &cur2);
-    todo_wine ok(status == STATUS_TIMER_RESOLUTION_NOT_SET, "NtSetTimerResolution() failed %x\n", status);
-    todo_wine ok(cur2 == cur, "expected requested timer resolution %u, got %u\n", cur, cur2);
+    ok(status == STATUS_TIMER_RESOLUTION_NOT_SET, "NtSetTimerResolution() failed %x\n", status);
+    ok(cur2 == cur, "expected requested timer resolution %u, got %u\n", cur, cur2);
 
     cur2 = 7654321;
     status = NtSetTimerResolution(min + 1, TRUE, &cur2);
-    todo_wine ok(status == STATUS_SUCCESS, "NtSetTimerResolution() failed %x\n", status);
+    ok(status == STATUS_SUCCESS, "NtSetTimerResolution() failed %x\n", status);
     /* This works because:
      * - Either cur is the minimum (15.6 ms) resolution already, i.e. the
      *   closest valid value 'set' is rounded to.
@@ -310,8 +310,8 @@ static void test_TimerResolution(void)
     cur2 = 7654321;
     set = max < cur ? cur - 1 : max;
     status = NtSetTimerResolution(set, TRUE, &cur2);
-    todo_wine ok(status == STATUS_SUCCESS, "NtSetTimerResolution() failed %x\n", status);
-    todo_wine ok(cur2 <= set, "expected new timer resolution %u <= %u\n", cur2, set);
+    ok(status == STATUS_SUCCESS, "NtSetTimerResolution() failed %x\n", status);
+    ok(cur2 <= set, "expected new timer resolution %u <= %u\n", cur2, set);
     trace("timer resolution: %u(max) <= %u(cur) <= %u(prev) <= %u(min)\n", max, cur2, cur, min);
 
     cur2 = 7654321;
@@ -321,8 +321,8 @@ static void test_TimerResolution(void)
     /* Cleanup by rescinding the last request */
     cur2 = 7654321;
     status = NtSetTimerResolution(0, FALSE, &cur2);
-    todo_wine ok(status == STATUS_SUCCESS, "NtSetTimerResolution() failed %x\n", status);
-    todo_wine ok(cur2 == cur, "expected requested timer resolution %u, got %u\n", set, cur2);
+    ok(status == STATUS_SUCCESS, "NtSetTimerResolution() failed %x\n", status);
+    ok(cur2 == cur, "expected requested timer resolution %u, got %u\n", set, cur2);
 }
 
 static void test_RtlQueryTimeZoneInformation(void)
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
index 7bdce91e034..d839195fd07 100644
--- a/dlls/ntdll/unix/sync.c
+++ b/dlls/ntdll/unix/sync.c
@@ -1599,8 +1599,13 @@ NTSTATUS WINAPI NtSetSystemTime( const LARGE_INTEGER *new, LARGE_INTEGER *old )
  */
 NTSTATUS WINAPI NtQueryTimerResolution( ULONG *min_res, ULONG *max_res, ULONG *current_res )
 {
-    FIXME( "(%p,%p,%p), stub!\n", min_res, max_res, current_res );
-    return STATUS_NOT_IMPLEMENTED;
+    TRACE( "(%p,%p,%p)\n", min_res, max_res, current_res );
+    if (!min_res || !max_res || !current_res)
+        return STATUS_ACCESS_VIOLATION;
+
+    *max_res = *current_res = 10000; /* See NtSetTimerResolution() */
+    *min_res = 156250;
+    return STATUS_SUCCESS;
 }
 
 
@@ -1609,8 +1614,28 @@ NTSTATUS WINAPI NtQueryTimerResolution( ULONG *min_res, ULONG *max_res, ULONG *c
  */
 NTSTATUS WINAPI NtSetTimerResolution( ULONG res, BOOLEAN set, ULONG *current_res )
 {
-    FIXME( "(%u,%u,%p), stub!\n", res, set, current_res );
-    return STATUS_NOT_IMPLEMENTED;
+    static BOOL has_request = FALSE;
+    TRACE( "(%u,%u,%p), semi-stub!\n", res, set, current_res );
+
+    if (!current_res)
+        return STATUS_ACCESS_VIOLATION;
+
+    /* Wine has no support for anything other that 1 ms and does not keep of
+     * track resolution requests anyway.
+     * Fortunately NtSetTimerResolution() should ignore requests to lower the
+     * timer resolution. So by claiming that 'some other process' requested the
+     * max resolution already, there no need to actually change it.
+     */
+    *current_res = 10000;
+
+    /* Just keep track of whether this process requested a specific timer
+     * resolution.
+     */
+    if (!has_request && !set)
+        return STATUS_TIMER_RESOLUTION_NOT_SET;
+    has_request = set;
+
+    return STATUS_SUCCESS;
 }
 
 
-- 
2.20.1



More information about the wine-devel mailing list