4 * Copyright (c) 2005 Robert Reif
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #include "wine/test.h"
34 #include "winmm_test.h"
38 static void test_timeGetDevCaps(void)
42 rc
= timeGetDevCaps(&tc
, 0);
43 ok(rc
== TIMERR_NOCANDO
|| rc
== MMSYSERR_INVALPARAM
,
44 "timeGetDevCaps() returned %s, should have returned TIMERR_NOCANDO "
45 "or MMSYSERR_INVALPARAM\n", mmsys_error(rc
));
47 rc
= timeGetDevCaps(0, sizeof(tc
));
48 ok(rc
== TIMERR_NOCANDO
|| rc
== TIMERR_STRUCT
,
49 "timeGetDevCaps() returned %s, should have returned TIMERR_NOCANDO "
50 "or TIMERR_STRUCT\n", mmsys_error(rc
));
52 rc
= timeGetDevCaps(0, 0);
53 ok(rc
== TIMERR_NOCANDO
|| rc
== MMSYSERR_INVALPARAM
,
54 "timeGetDevCaps() returned %s, should have returned TIMERR_NOCANDO "
55 "or MMSYSERR_INVALPARAM\n", mmsys_error(rc
));
57 rc
= timeGetDevCaps(&tc
, sizeof(tc
));
58 ok(rc
== TIMERR_NOERROR
, "timeGetDevCaps() returned %s, "
59 "should have returned TIMERR_NOERROR\n", mmsys_error(rc
));
61 if (rc
== TIMERR_NOERROR
)
62 trace("wPeriodMin = %u, wPeriodMax = %u\n",
63 tc
.wPeriodMin
, tc
.wPeriodMax
);
66 #define NUM_SAMPLES 100
68 static DWORD count
= 0;
69 static DWORD times
[NUM_SAMPLES
];
71 static void CALLBACK
testTimeProc(UINT uID
, UINT uMsg
, DWORD_PTR dwUser
,
72 DWORD_PTR dw1
, DWORD_PTR dw2
)
74 if (count
< NUM_SAMPLES
)
75 times
[count
++] = timeGetTime();
78 static void test_timer(UINT period
, UINT resolution
)
82 DWORD dwMin
= 0xffffffff, dwMax
= 0;
84 double deviation
= 0.0;
88 for (i
= 0; i
< NUM_SAMPLES
; i
++)
91 rc
= timeBeginPeriod(period
);
92 ok(rc
== TIMERR_NOERROR
, "timeBeginPeriod(%u) returned %s, "
93 "should have returned TIMERR_NOERROR\n", period
, mmsys_error(rc
));
94 if (rc
!= TIMERR_NOERROR
)
97 id
= timeSetEvent(period
, resolution
, testTimeProc
, 0, TIME_PERIODIC
);
98 ok(id
!= 0, "timeSetEvent(%u, %u, %p, 0, TIME_PERIODIC) returned %d, "
99 "should have returned id > 0\n", period
, resolution
, testTimeProc
, id
);
103 Sleep((NUM_SAMPLES
* period
) + (2 * period
));
105 rc
= timeEndPeriod(period
);
106 ok(rc
== TIMERR_NOERROR
, "timeEndPeriod(%u) returned %s, "
107 "should have returned TIMERR_NOERROR\n", period
, mmsys_error(rc
));
108 if (rc
!= TIMERR_NOERROR
)
111 rc
= timeKillEvent(id
);
112 ok(rc
== TIMERR_NOERROR
, "timeKillEvent(%u) returned %s, "
113 "should have returned TIMERR_NOERROR\n", id
, mmsys_error(rc
));
115 trace("period = %u, resolution = %u\n", period
, resolution
);
117 for (i
= 0; i
< count
; i
++)
121 if (winetest_debug
> 1)
122 trace("time[%d] = %u\n", i
, times
[i
]);
126 delta
= times
[i
] - times
[i
- 1];
128 if (winetest_debug
> 1)
129 trace("time[%d] = %u delta = %d\n", i
, times
[i
], delta
);
132 deviation
+= ((delta
- period
) * (delta
- period
));
142 trace("min = %u, max = %u, average = %f, standard deviation = %f\n",
143 dwMin
, dwMax
, sum
/ (count
- 1), sqrt(deviation
/ (count
- 2)));
146 static const char * get_priority(int priority
)
149 #define STR(x) case x: return #x
151 STR(THREAD_PRIORITY_LOWEST
);
152 STR(THREAD_PRIORITY_BELOW_NORMAL
);
153 STR(THREAD_PRIORITY_NORMAL
);
154 STR(THREAD_PRIORITY_HIGHEST
);
155 STR(THREAD_PRIORITY_ABOVE_NORMAL
);
156 STR(THREAD_PRIORITY_TIME_CRITICAL
);
157 STR(THREAD_PRIORITY_IDLE
);
159 sprintf(tmp
, "UNKNOWN(%d)", priority
);
163 static int priority
= 0;
164 static BOOL fired
= FALSE
;
166 static void CALLBACK
priorityTimeProc(UINT uID
, UINT uMsg
, DWORD_PTR dwUser
,
167 DWORD_PTR dw1
, DWORD_PTR dw2
)
169 priority
= GetThreadPriority(GetCurrentThread());
170 ok(priority
!=THREAD_PRIORITY_ERROR_RETURN
, "GetThreadPriority() failed, GetLastError() = %u\n", GetLastError());
174 static void test_priority(void)
178 id
= timeSetEvent(100, 100, priorityTimeProc
, 0, TIME_ONESHOT
);
179 ok(id
!= 0, "timeSetEvent(100, 100, %p, 0, TIME_ONESHOT) returned %d, "
180 "should have returned id > 0\n", priorityTimeProc
, id
);
186 ok(fired
== TRUE
, "Callback not called\n");
189 ok(priority
== THREAD_PRIORITY_TIME_CRITICAL
,
190 "thread priority is %s, should be THREAD_PRIORITY_TIME_CRITICAL\n",
191 get_priority(priority
));
196 static void CALLBACK
kill_timer_callback(UINT id
, UINT msg
,
197 DWORD_PTR arg
, DWORD_PTR dw1
, DWORD_PTR dw2
)
199 HANDLE event
= (HANDLE
)arg
;
202 res
= timeKillEvent(id
);
203 ok(res
== TIMERR_NOERROR
, "timeKillEvent failed in callback\n");
207 static void test_timer_lifetime(void)
213 event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
214 ok(event
!= NULL
, "CreateEvent failed\n");
216 for (i
= 0; i
< 20; i
++)
218 timers
[i
] = timeSetEvent(10000, 0, event
, 0, TIME_CALLBACK_EVENT_SET
);
220 ok(timers
[i
] != 0, "%d) timeSetEvent failed\n", i
);
222 ok(!timers
[i
], "%d) timeSetEvent succeeded\n", i
);
225 for (i
= 0; i
< 16; i
++)
227 res
= timeKillEvent(timers
[i
]);
228 ok(res
== TIMERR_NOERROR
, "%d) timeKillEvent failed\n", i
);
231 timers
[0] = timeSetEvent(10, 0, event
, 0, TIME_CALLBACK_EVENT_SET
);
232 ok(timers
[0], "timeSetEvent failed\n");
233 WaitForSingleObject(event
, 1000);
234 timers
[1] = timeSetEvent(1000, 0, event
, 0, TIME_CALLBACK_EVENT_SET
);
235 ok(timers
[1], "timeSetEvent failed\n");
236 ok(timers
[0] != timers
[1], "timer got the same id as just destroyed timer\n");
237 res
= timeKillEvent(timers
[0]);
238 ok(res
== TIMERR_NOCANDO
, "timeKillEvent returned %d\n", res
);
239 res
= timeKillEvent(timers
[1]);
240 ok(res
== TIMERR_NOERROR
, "timeKillEvent returned %d\n", res
);
242 timers
[0] = timeSetEvent(10, 0, kill_timer_callback
, (DWORD_PTR
)event
, TIME_ONESHOT
);
243 WaitForSingleObject(event
, 1000);
244 timers
[0] = timeSetEvent(10, 0, kill_timer_callback
, (DWORD_PTR
)event
, TIME_KILL_SYNCHRONOUS
);
245 WaitForSingleObject(event
, 1000);
252 test_timeGetDevCaps();
254 if (tc
.wPeriodMin
<= 1) {
259 if (tc
.wPeriodMin
<= 10) {
265 if (tc
.wPeriodMin
<= 20) {
273 test_timer_lifetime();