ntdll: Improve the Nt{Query,Set}TimerResolution() stubs.
Signed-off-by: Francois Gouget <fgouget@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
6015fee5b2
commit
d84e84c126
|
@ -195,7 +195,7 @@ static void test_Sleep(void)
|
||||||
/* Get the timer resolution before... */
|
/* Get the timer resolution before... */
|
||||||
r1 = 156250;
|
r1 = 156250;
|
||||||
status = NtQueryTimerResolution(&dummy, &dummy, &r1);
|
status = NtQueryTimerResolution(&dummy, &dummy, &r1);
|
||||||
todo_wine ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%x)\n", status);
|
ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%x)\n", status);
|
||||||
|
|
||||||
for (i = 0; i < 50; i++) {
|
for (i = 0; i < 50; i++) {
|
||||||
Sleep(1);
|
Sleep(1);
|
||||||
|
@ -207,15 +207,15 @@ static void test_Sleep(void)
|
||||||
/* ...and after in case some other process changes it during this test */
|
/* ...and after in case some other process changes it during this test */
|
||||||
r2 = 156250;
|
r2 = 156250;
|
||||||
status = NtQueryTimerResolution(&dummy, &dummy, &r2);
|
status = NtQueryTimerResolution(&dummy, &dummy, &r2);
|
||||||
todo_wine ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%x)\n", status);
|
ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%x)\n", status);
|
||||||
|
|
||||||
elapsed_time = (t2.QuadPart - t1.QuadPart) / (double)frequency.QuadPart;
|
elapsed_time = (t2.QuadPart - t1.QuadPart) / (double)frequency.QuadPart;
|
||||||
min = 50.0 * (r1 < r2 ? r1 : r2) / 10000000.0;
|
min = 50.0 * (r1 < r2 ? r1 : r2) / 10000000.0;
|
||||||
max = 50.0 * (r1 < r2 ? r2 : r1) / 10000000.0;
|
max = 50.0 * (r1 < r2 ? r2 : r1) / 10000000.0;
|
||||||
|
|
||||||
/* Add an extra 1s to account for potential scheduling delays */
|
/* Add an extra 1s to account for potential scheduling delays */
|
||||||
todo_wine ok(0.9 * min <= elapsed_time && elapsed_time <= 1.0 + max,
|
ok(0.9 * min <= elapsed_time && elapsed_time <= 1.0 + max,
|
||||||
"got %f, expected between %f and %f\n", elapsed_time, min, max);
|
"got %f, expected between %f and %f\n", elapsed_time, min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
START_TEST(sync)
|
START_TEST(sync)
|
||||||
|
|
|
@ -218,16 +218,16 @@ static void test_RtlQueryPerformanceCounter(void)
|
||||||
|
|
||||||
#define CHECK_CURRENT_TIMER(expected) \
|
#define CHECK_CURRENT_TIMER(expected) \
|
||||||
do { \
|
do { \
|
||||||
todo_wine ok(status == STATUS_SUCCESS, "NtSetTimerResolution failed %x\n", status); \
|
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(cur2 == (expected), "expected new timer resolution %u, got %u\n", (expected), cur2); \
|
||||||
min2 = min + 10; \
|
min2 = min + 10; \
|
||||||
cur2 = min2 + 1; \
|
cur2 = min2 + 1; \
|
||||||
max2 = cur2 + 1; \
|
max2 = cur2 + 1; \
|
||||||
status = NtQueryTimerResolution(&min2, &max2, &cur2); \
|
status = NtQueryTimerResolution(&min2, &max2, &cur2); \
|
||||||
todo_wine ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed %x\n", status); \
|
ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed %x\n", status); \
|
||||||
todo_wine ok(min2 == min, "NtQueryTimerResolution() expected min=%u, got %u\n", min, min2); \
|
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); \
|
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(cur2 == expected, "NtQueryTimerResolution() expected timer resolution %u, got %u\n", (expected), cur2); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static void test_TimerResolution(void)
|
static void test_TimerResolution(void)
|
||||||
|
@ -236,46 +236,46 @@ static void test_TimerResolution(void)
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
|
||||||
status = NtQueryTimerResolution(NULL, &max, &cur);
|
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);
|
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);
|
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;
|
min = 212121;
|
||||||
cur = min + 1;
|
cur = min + 1;
|
||||||
max = cur + 1;
|
max = cur + 1;
|
||||||
status = NtQueryTimerResolution(&min, &max, &cur);
|
status = NtQueryTimerResolution(&min, &max, &cur);
|
||||||
todo_wine ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%x)\n", status);
|
ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%x)\n", status);
|
||||||
todo_wine ok(min == 156250 /* 1/64s HPET */ || min == 156001 /* RTC */,
|
ok(min == 156250 /* 1/64s HPET */ || min == 156001 /* RTC */,
|
||||||
"unexpected minimum timer resolution %u\n", min);
|
"unexpected minimum timer resolution %u\n", min);
|
||||||
ok(0 < max, "invalid maximum timer resolution, should be 0 < %u\n", max);
|
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);
|
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 */
|
/* Nothing happens if that pointer is not good */
|
||||||
status = NtSetTimerResolution(cur - 1, TRUE, NULL);
|
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;
|
min2 = min + 1;
|
||||||
cur2 = min2 + 1;
|
cur2 = min2 + 1;
|
||||||
max2 = cur2 + 1;
|
max2 = cur2 + 1;
|
||||||
status = NtQueryTimerResolution(&min2, &max2, &cur2);
|
status = NtQueryTimerResolution(&min2, &max2, &cur2);
|
||||||
todo_wine ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%x)\n", status);
|
ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%x)\n", status);
|
||||||
todo_wine ok(min2 == min, "NtQueryTimerResolution() expected min=%u, got %u\n", min, min2);
|
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);
|
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(cur2 == cur, "NtQueryTimerResolution() expected timer resolution %u, got %u\n", cur, cur2);
|
||||||
|
|
||||||
/* 'fails' until the first valid timer resolution request */
|
/* 'fails' until the first valid timer resolution request */
|
||||||
cur2 = 7654321;
|
cur2 = 7654321;
|
||||||
status = NtSetTimerResolution(0, FALSE, &cur2);
|
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 */
|
/* 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;
|
cur2 = 7654321;
|
||||||
|
@ -285,18 +285,18 @@ static void test_TimerResolution(void)
|
||||||
/* Rescinds our timer resolution request */
|
/* Rescinds our timer resolution request */
|
||||||
cur2 = 7654321;
|
cur2 = 7654321;
|
||||||
status = NtSetTimerResolution(0, FALSE, &cur2);
|
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 */
|
/* -> 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;
|
cur2 = 7654321;
|
||||||
status = NtSetTimerResolution(0, FALSE, &cur2);
|
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);
|
||||||
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;
|
cur2 = 7654321;
|
||||||
status = NtSetTimerResolution(min + 1, TRUE, &cur2);
|
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:
|
/* This works because:
|
||||||
* - Either cur is the minimum (15.6 ms) resolution already, i.e. the
|
* - Either cur is the minimum (15.6 ms) resolution already, i.e. the
|
||||||
* closest valid value 'set' is rounded to.
|
* closest valid value 'set' is rounded to.
|
||||||
|
@ -310,8 +310,8 @@ static void test_TimerResolution(void)
|
||||||
cur2 = 7654321;
|
cur2 = 7654321;
|
||||||
set = max < cur ? cur - 1 : max;
|
set = max < cur ? cur - 1 : max;
|
||||||
status = NtSetTimerResolution(set, TRUE, &cur2);
|
status = NtSetTimerResolution(set, TRUE, &cur2);
|
||||||
todo_wine ok(status == STATUS_SUCCESS, "NtSetTimerResolution() failed %x\n", status);
|
ok(status == STATUS_SUCCESS, "NtSetTimerResolution() failed %x\n", status);
|
||||||
todo_wine ok(cur2 <= set, "expected new timer resolution %u <= %u\n", cur2, set);
|
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);
|
trace("timer resolution: %u(max) <= %u(cur) <= %u(prev) <= %u(min)\n", max, cur2, cur, min);
|
||||||
|
|
||||||
cur2 = 7654321;
|
cur2 = 7654321;
|
||||||
|
@ -321,8 +321,8 @@ static void test_TimerResolution(void)
|
||||||
/* Cleanup by rescinding the last request */
|
/* Cleanup by rescinding the last request */
|
||||||
cur2 = 7654321;
|
cur2 = 7654321;
|
||||||
status = NtSetTimerResolution(0, FALSE, &cur2);
|
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);
|
||||||
todo_wine ok(cur2 == cur, "expected requested timer resolution %u, got %u\n", set, cur2);
|
ok(cur2 == cur, "expected requested timer resolution %u, got %u\n", set, cur2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_RtlQueryTimeZoneInformation(void)
|
static void test_RtlQueryTimeZoneInformation(void)
|
||||||
|
|
|
@ -1599,8 +1599,10 @@ NTSTATUS WINAPI NtSetSystemTime( const LARGE_INTEGER *new, LARGE_INTEGER *old )
|
||||||
*/
|
*/
|
||||||
NTSTATUS WINAPI NtQueryTimerResolution( ULONG *min_res, ULONG *max_res, ULONG *current_res )
|
NTSTATUS WINAPI NtQueryTimerResolution( ULONG *min_res, ULONG *max_res, ULONG *current_res )
|
||||||
{
|
{
|
||||||
FIXME( "(%p,%p,%p), stub!\n", min_res, max_res, current_res );
|
TRACE( "(%p,%p,%p)\n", min_res, max_res, current_res );
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
*max_res = *current_res = 10000; /* See NtSetTimerResolution() */
|
||||||
|
*min_res = 156250;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1609,8 +1611,26 @@ NTSTATUS WINAPI NtQueryTimerResolution( ULONG *min_res, ULONG *max_res, ULONG *c
|
||||||
*/
|
*/
|
||||||
NTSTATUS WINAPI NtSetTimerResolution( ULONG res, BOOLEAN set, ULONG *current_res )
|
NTSTATUS WINAPI NtSetTimerResolution( ULONG res, BOOLEAN set, ULONG *current_res )
|
||||||
{
|
{
|
||||||
FIXME( "(%u,%u,%p), stub!\n", res, set, current_res );
|
static BOOL has_request = FALSE;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
|
||||||
|
TRACE( "(%u,%u,%p), semi-stub!\n", res, set, current_res );
|
||||||
|
|
||||||
|
/* 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue