user32/tests: Improve timer measurement method.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55786
This commit is contained in:
parent
d81256e7b6
commit
0f0867063d
1 changed files with 71 additions and 35 deletions
|
@ -11548,20 +11548,67 @@ static VOID CALLBACK tfunc(HWND hwnd, UINT uMsg, UINT_PTR id, DWORD dwTime)
|
|||
{
|
||||
}
|
||||
|
||||
#define TIMER_ID 0x19
|
||||
#define TIMER_COUNT_EXPECTED 100
|
||||
#define TIMER_COUNT_TOLERANCE 10
|
||||
#define TIMER_ID 0x19
|
||||
#define TIMER_COUNT 500 /* 499 samples */
|
||||
#define TIMER_DURATION_EXPECTED 10000 /* 10 ms */
|
||||
#define TIMER_DURATION_ALT 15600 /* 15.6 ms */
|
||||
#define TIMER_DURATION_TOLERANCE 1000 /* 1 ms */
|
||||
|
||||
static int count = 0;
|
||||
static ULONGLONG timer_ticks[TIMER_COUNT];
|
||||
static int timer_duration = 0;
|
||||
|
||||
static int compare_ulonglong(const void *a, const void *b)
|
||||
{
|
||||
ULONGLONG la, lb;
|
||||
la = *(ULONGLONG*)a;
|
||||
lb = *(ULONGLONG*)b;
|
||||
return (la > lb) - (la < lb);
|
||||
}
|
||||
|
||||
static void timer_fired(void)
|
||||
{
|
||||
if (count < TIMER_COUNT)
|
||||
{
|
||||
LARGE_INTEGER performance_counter;
|
||||
BOOL ret;
|
||||
|
||||
ret = QueryPerformanceCounter(&performance_counter);
|
||||
ok(ret, "QueryPerformanceCounter failed\n");
|
||||
|
||||
timer_ticks[count] = performance_counter.QuadPart;
|
||||
}
|
||||
|
||||
count++;
|
||||
|
||||
if (count == TIMER_COUNT)
|
||||
{
|
||||
LARGE_INTEGER performance_frequency;
|
||||
BOOL ret;
|
||||
|
||||
/* calculate durations */
|
||||
for (int i=0; i < TIMER_COUNT-1; i++)
|
||||
timer_ticks[i] = timer_ticks[i+1] - timer_ticks[i];
|
||||
|
||||
qsort(timer_ticks, TIMER_COUNT - 1, sizeof(timer_ticks[0]), compare_ulonglong);
|
||||
|
||||
ret = QueryPerformanceFrequency(&performance_frequency);
|
||||
ok(ret, "QueryPerformanceFrequency failed\n");
|
||||
|
||||
/* median duration, converted to microseconds */
|
||||
timer_duration = (int)(timer_ticks[(TIMER_COUNT - 1) / 2] * 1000000 / performance_frequency.QuadPart);
|
||||
}
|
||||
}
|
||||
|
||||
static void CALLBACK callback_count(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
|
||||
{
|
||||
count++;
|
||||
timer_fired();
|
||||
}
|
||||
|
||||
static DWORD exception;
|
||||
static void CALLBACK callback_exception(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
|
||||
{
|
||||
count++;
|
||||
timer_fired();
|
||||
RaiseException(exception, 0, 0, NULL);
|
||||
}
|
||||
|
||||
|
@ -11583,7 +11630,6 @@ static DWORD WINAPI timer_thread_proc(LPVOID x)
|
|||
static void test_timers(void)
|
||||
{
|
||||
struct timer_info info;
|
||||
DWORD start;
|
||||
DWORD id;
|
||||
MSG msg;
|
||||
|
||||
|
@ -11609,44 +11655,37 @@ static void test_timers(void)
|
|||
|
||||
/* Check the minimum allowed timeout for a timer. MSDN indicates that it should be 10.0 ms,
|
||||
* which occurs sometimes, but most testing on the VMs indicates a minimum timeout closer to
|
||||
* 15.6 ms. Since there is some measurement error between test runs we are allowing for
|
||||
* ±9 counts (~4 ms) around the expected value.
|
||||
* 15.6 ms.
|
||||
*/
|
||||
count = 0;
|
||||
id = SetTimer(info.hWnd, TIMER_ID, 0, callback_count);
|
||||
ok(id != 0, "did not get id from SetTimer.\n");
|
||||
ok(id==TIMER_ID, "SetTimer timer ID different\n");
|
||||
start = GetTickCount();
|
||||
while (GetTickCount()-start < 1001 && GetMessageA(&msg, info.hWnd, 0, 0))
|
||||
while (count < TIMER_COUNT && GetMessageA(&msg, info.hWnd, 0, 0))
|
||||
DispatchMessageA(&msg);
|
||||
ok(abs(count-TIMER_COUNT_EXPECTED) < TIMER_COUNT_TOLERANCE /* xp */
|
||||
|| broken(abs(count-64) <= TIMER_COUNT_TOLERANCE) /* most common */
|
||||
|| broken(abs(count-43) <= TIMER_COUNT_TOLERANCE) /* w2k3, win8 */,
|
||||
"did not get expected count for minimum timeout (%d != ~%d).\n",
|
||||
count, TIMER_COUNT_EXPECTED);
|
||||
ok(abs(timer_duration-TIMER_DURATION_EXPECTED) < TIMER_DURATION_TOLERANCE /* xp, win7 */
|
||||
|| broken(abs(timer_duration - TIMER_DURATION_ALT) < TIMER_DURATION_TOLERANCE) /* most common */,
|
||||
"did not get expected median timeout (%d != ~%d).\n",
|
||||
timer_duration, TIMER_DURATION_EXPECTED);
|
||||
ok(KillTimer(info.hWnd, id), "KillTimer failed\n");
|
||||
/* Perform the same check on SetSystemTimer (only available on w2k3 and older) */
|
||||
if (pSetSystemTimer)
|
||||
{
|
||||
int syscount = 0;
|
||||
|
||||
count = 0;
|
||||
id = pSetSystemTimer(info.hWnd, TIMER_ID, 0, callback_count);
|
||||
ok(id != 0, "did not get id from SetSystemTimer.\n");
|
||||
ok(id==TIMER_ID, "SetTimer timer ID different\n");
|
||||
start = GetTickCount();
|
||||
while (GetTickCount()-start < 1001 && GetMessageA(&msg, info.hWnd, 0, 0))
|
||||
while (count < TIMER_COUNT && GetMessageA(&msg, info.hWnd, 0, 0))
|
||||
{
|
||||
if (msg.message == WM_SYSTIMER)
|
||||
syscount++;
|
||||
timer_fired();
|
||||
ok(msg.message != WM_TIMER, "unexpected WM_TIMER\n");
|
||||
DispatchMessageA(&msg);
|
||||
}
|
||||
ok(abs(syscount-TIMER_COUNT_EXPECTED) < TIMER_COUNT_TOLERANCE
|
||||
|| broken(abs(syscount-64) < TIMER_COUNT_TOLERANCE) /* most common */
|
||||
|| broken(syscount > 4000 && syscount < 12000) /* win2k3sp0 */,
|
||||
"did not get expected count for minimum timeout (%d != ~%d).\n",
|
||||
syscount, TIMER_COUNT_EXPECTED);
|
||||
ok(count == 0, "did not get expected count for callback timeout (%d != 0).\n", count);
|
||||
ok(abs(timer_duration-TIMER_DURATION_EXPECTED) < TIMER_DURATION_TOLERANCE
|
||||
|| broken(abs(timer_duration - TIMER_DURATION_ALT) < TIMER_DURATION_TOLERANCE) /* most common */,
|
||||
"did not get expected median timeout (%d != ~%d).\n",
|
||||
timer_duration, TIMER_DURATION_EXPECTED);
|
||||
ok(pKillSystemTimer(info.hWnd, id), "KillSystemTimer failed\n");
|
||||
}
|
||||
|
||||
|
@ -11679,20 +11718,17 @@ static void test_timers_no_wnd(void)
|
|||
|
||||
/* Check the minimum allowed timeout for a timer. MSDN indicates that it should be 10.0 ms,
|
||||
* which occurs sometimes, but most testing on the VMs indicates a minimum timeout closer to
|
||||
* 15.6 ms. Since there is some measurement error between test runs we are allowing for
|
||||
* ±9 counts (~4 ms) around the expected value.
|
||||
* 15.6 ms.
|
||||
*/
|
||||
count = 0;
|
||||
id = SetTimer(NULL, 0, 0, callback_count);
|
||||
ok(id != 0, "did not get id from SetTimer.\n");
|
||||
start = GetTickCount();
|
||||
while (GetTickCount()-start < 1001 && GetMessageA(&msg, NULL, 0, 0))
|
||||
while (count < TIMER_COUNT && GetMessageA(&msg, NULL, 0, 0))
|
||||
DispatchMessageA(&msg);
|
||||
ok(abs(count-TIMER_COUNT_EXPECTED) < TIMER_COUNT_TOLERANCE /* xp */
|
||||
|| broken(abs(count-64) <= TIMER_COUNT_TOLERANCE) /* most common */
|
||||
|| broken(abs(count-43) <= TIMER_COUNT_TOLERANCE) /* w1064v1809 */,
|
||||
"did not get expected count for minimum timeout (%d != ~%d).\n",
|
||||
count, TIMER_COUNT_EXPECTED);
|
||||
ok(abs(timer_duration-TIMER_DURATION_EXPECTED) < TIMER_DURATION_TOLERANCE /* xp */
|
||||
|| broken(abs(timer_duration - TIMER_DURATION_ALT) < TIMER_DURATION_TOLERANCE) /* most common */,
|
||||
"did not get expected median timeout (%d != ~%d).\n",
|
||||
timer_duration, TIMER_DURATION_EXPECTED);
|
||||
KillTimer(NULL, id);
|
||||
/* Note: SetSystemTimer doesn't support a NULL window, see test_timers */
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue