]> git.proxmox.com Git - mirror_qemu.git/blob - tests/ptimer-test.c
Merge remote-tracking branch 'remotes/famz/tags/various-pull-request' into staging
[mirror_qemu.git] / tests / ptimer-test.c
1 /*
2 * QTest testcase for the ptimer
3 *
4 * Author: Dmitry Osipenko <digetx@gmail.com>
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2 or later.
7 * See the COPYING file in the top-level directory.
8 *
9 */
10
11 #include <glib/gprintf.h>
12
13 #include "qemu/osdep.h"
14 #include "qemu/main-loop.h"
15 #include "hw/ptimer.h"
16
17 #include "libqtest.h"
18 #include "ptimer-test.h"
19
20 static bool triggered;
21
22 static void ptimer_trigger(void *opaque)
23 {
24 triggered = true;
25 }
26
27 static void ptimer_test_expire_qemu_timers(int64_t expire_time,
28 QEMUClockType type)
29 {
30 QEMUTimerList *timer_list = main_loop_tlg.tl[type];
31 QEMUTimer *t = timer_list->active_timers.next;
32
33 while (t != NULL) {
34 if (t->expire_time == expire_time) {
35 timer_del(t);
36
37 if (t->cb != NULL) {
38 t->cb(t->opaque);
39 }
40 }
41
42 t = t->next;
43 }
44 }
45
46 static void ptimer_test_set_qemu_time_ns(int64_t ns)
47 {
48 ptimer_test_time_ns = ns;
49 }
50
51 static void qemu_clock_step(uint64_t ns)
52 {
53 int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
54 int64_t advanced_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns;
55
56 while (deadline != -1 && deadline <= advanced_time) {
57 ptimer_test_set_qemu_time_ns(deadline);
58 ptimer_test_expire_qemu_timers(deadline, QEMU_CLOCK_VIRTUAL);
59 deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
60 }
61
62 ptimer_test_set_qemu_time_ns(advanced_time);
63 }
64
65 static void check_set_count(gconstpointer arg)
66 {
67 const uint8_t *policy = arg;
68 QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
69 ptimer_state *ptimer = ptimer_init(bh, *policy);
70
71 triggered = false;
72
73 ptimer_set_count(ptimer, 1000);
74 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 1000);
75 g_assert_false(triggered);
76 }
77
78 static void check_set_limit(gconstpointer arg)
79 {
80 const uint8_t *policy = arg;
81 QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
82 ptimer_state *ptimer = ptimer_init(bh, *policy);
83
84 triggered = false;
85
86 ptimer_set_limit(ptimer, 1000, 0);
87 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
88 g_assert_cmpuint(ptimer_get_limit(ptimer), ==, 1000);
89 g_assert_false(triggered);
90
91 ptimer_set_limit(ptimer, 2000, 1);
92 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 2000);
93 g_assert_cmpuint(ptimer_get_limit(ptimer), ==, 2000);
94 g_assert_false(triggered);
95 }
96
97 static void check_oneshot(gconstpointer arg)
98 {
99 const uint8_t *policy = arg;
100 QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
101 ptimer_state *ptimer = ptimer_init(bh, *policy);
102
103 triggered = false;
104
105 ptimer_set_period(ptimer, 2000000);
106 ptimer_set_count(ptimer, 10);
107 ptimer_run(ptimer, 1);
108
109 qemu_clock_step(2000000 * 2 + 100000);
110
111 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 7);
112 g_assert_false(triggered);
113
114 ptimer_stop(ptimer);
115
116 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 7);
117 g_assert_false(triggered);
118
119 qemu_clock_step(2000000 * 11);
120
121 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 7);
122 g_assert_false(triggered);
123
124 ptimer_run(ptimer, 1);
125
126 qemu_clock_step(2000000 * 7 + 100000);
127
128 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
129 g_assert_true(triggered);
130
131 triggered = false;
132
133 qemu_clock_step(2000000);
134
135 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
136 g_assert_false(triggered);
137
138 qemu_clock_step(4000000);
139
140 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
141 g_assert_false(triggered);
142
143 ptimer_set_count(ptimer, 10);
144
145 qemu_clock_step(20000000 + 100000);
146
147 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
148 g_assert_false(triggered);
149
150 ptimer_set_limit(ptimer, 9, 1);
151
152 qemu_clock_step(20000000 + 100000);
153
154 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 9);
155 g_assert_false(triggered);
156
157 ptimer_run(ptimer, 1);
158
159 qemu_clock_step(2000000 + 100000);
160
161 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 7);
162 g_assert_false(triggered);
163
164 ptimer_set_count(ptimer, 20);
165
166 qemu_clock_step(2000000 * 19 + 100000);
167
168 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
169 g_assert_false(triggered);
170
171 qemu_clock_step(2000000);
172
173 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
174 g_assert_true(triggered);
175
176 ptimer_stop(ptimer);
177
178 triggered = false;
179
180 qemu_clock_step(2000000 * 12 + 100000);
181
182 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
183 g_assert_false(triggered);
184 }
185
186 static void check_periodic(gconstpointer arg)
187 {
188 const uint8_t *policy = arg;
189 QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
190 ptimer_state *ptimer = ptimer_init(bh, *policy);
191
192 triggered = false;
193
194 ptimer_set_period(ptimer, 2000000);
195 ptimer_set_limit(ptimer, 10, 1);
196 ptimer_run(ptimer, 0);
197
198 qemu_clock_step(2000000 * 10 + 100000);
199
200 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 9);
201 g_assert_true(triggered);
202
203 triggered = false;
204
205 qemu_clock_step(2000000);
206
207 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 8);
208 g_assert_false(triggered);
209
210 ptimer_set_count(ptimer, 20);
211
212 qemu_clock_step(2000000 * 11 + 100000);
213
214 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 8);
215 g_assert_false(triggered);
216
217 qemu_clock_step(2000000 * 10);
218
219 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 8);
220 g_assert_true(triggered);
221
222 ptimer_stop(ptimer);
223 triggered = false;
224
225 qemu_clock_step(2000000);
226
227 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 8);
228 g_assert_false(triggered);
229
230 ptimer_set_count(ptimer, 3);
231 ptimer_run(ptimer, 0);
232
233 qemu_clock_step(2000000 * 3 + 100000);
234
235 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 9);
236 g_assert_true(triggered);
237
238 triggered = false;
239
240 qemu_clock_step(2000000);
241
242 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 8);
243 g_assert_false(triggered);
244
245 ptimer_set_count(ptimer, 0);
246 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
247 g_assert_true(triggered);
248
249 triggered = false;
250
251 qemu_clock_step(2000000 * 12 + 100000);
252
253 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 7);
254 g_assert_true(triggered);
255
256 ptimer_stop(ptimer);
257
258 triggered = false;
259
260 qemu_clock_step(2000000 * 12 + 100000);
261
262 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 7);
263 g_assert_false(triggered);
264
265 ptimer_run(ptimer, 0);
266 ptimer_set_period(ptimer, 0);
267
268 qemu_clock_step(2000000 + 100000);
269
270 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 7);
271 g_assert_false(triggered);
272 }
273
274 static void check_on_the_fly_mode_change(gconstpointer arg)
275 {
276 const uint8_t *policy = arg;
277 QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
278 ptimer_state *ptimer = ptimer_init(bh, *policy);
279
280 triggered = false;
281
282 ptimer_set_period(ptimer, 2000000);
283 ptimer_set_limit(ptimer, 10, 1);
284 ptimer_run(ptimer, 1);
285
286 qemu_clock_step(2000000 * 9 + 100000);
287
288 ptimer_run(ptimer, 0);
289
290 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
291 g_assert_false(triggered);
292
293 qemu_clock_step(2000000);
294
295 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 9);
296 g_assert_true(triggered);
297
298 triggered = false;
299
300 qemu_clock_step(2000000 * 9);
301
302 ptimer_run(ptimer, 1);
303
304 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
305 g_assert_false(triggered);
306
307 qemu_clock_step(2000000 * 3);
308
309 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
310 g_assert_true(triggered);
311 }
312
313 static void check_on_the_fly_period_change(gconstpointer arg)
314 {
315 const uint8_t *policy = arg;
316 QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
317 ptimer_state *ptimer = ptimer_init(bh, *policy);
318
319 triggered = false;
320
321 ptimer_set_period(ptimer, 2000000);
322 ptimer_set_limit(ptimer, 8, 1);
323 ptimer_run(ptimer, 1);
324
325 qemu_clock_step(2000000 * 4 + 100000);
326
327 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 3);
328 g_assert_false(triggered);
329
330 ptimer_set_period(ptimer, 4000000);
331 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 3);
332
333 qemu_clock_step(4000000 * 2 + 100000);
334
335 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
336 g_assert_false(triggered);
337
338 qemu_clock_step(4000000 * 2);
339
340 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
341 g_assert_true(triggered);
342 }
343
344 static void check_on_the_fly_freq_change(gconstpointer arg)
345 {
346 const uint8_t *policy = arg;
347 QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
348 ptimer_state *ptimer = ptimer_init(bh, *policy);
349
350 triggered = false;
351
352 ptimer_set_freq(ptimer, 500);
353 ptimer_set_limit(ptimer, 8, 1);
354 ptimer_run(ptimer, 1);
355
356 qemu_clock_step(2000000 * 4 + 100000);
357
358 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 3);
359 g_assert_false(triggered);
360
361 ptimer_set_freq(ptimer, 250);
362 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 3);
363
364 qemu_clock_step(2000000 * 4 + 100000);
365
366 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
367 g_assert_false(triggered);
368
369 qemu_clock_step(2000000 * 4);
370
371 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
372 g_assert_true(triggered);
373 }
374
375 static void check_run_with_period_0(gconstpointer arg)
376 {
377 const uint8_t *policy = arg;
378 QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
379 ptimer_state *ptimer = ptimer_init(bh, *policy);
380
381 triggered = false;
382
383 ptimer_set_count(ptimer, 99);
384 ptimer_run(ptimer, 1);
385
386 qemu_clock_step(10 * NANOSECONDS_PER_SECOND);
387
388 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 99);
389 g_assert_false(triggered);
390 }
391
392 static void check_run_with_delta_0(gconstpointer arg)
393 {
394 const uint8_t *policy = arg;
395 QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
396 ptimer_state *ptimer = ptimer_init(bh, *policy);
397
398 triggered = false;
399
400 ptimer_set_period(ptimer, 2000000);
401 ptimer_set_limit(ptimer, 99, 0);
402 ptimer_run(ptimer, 1);
403 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 99);
404 g_assert_true(triggered);
405
406 triggered = false;
407
408 qemu_clock_step(2000000 + 100000);
409
410 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 97);
411 g_assert_false(triggered);
412
413 qemu_clock_step(2000000 * 97);
414
415 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
416 g_assert_false(triggered);
417
418 qemu_clock_step(2000000 * 2);
419
420 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
421 g_assert_true(triggered);
422
423 triggered = false;
424
425 ptimer_set_count(ptimer, 0);
426 ptimer_run(ptimer, 0);
427 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 99);
428 g_assert_true(triggered);
429
430 triggered = false;
431
432 qemu_clock_step(2000000 + 100000);
433
434 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 97);
435 g_assert_false(triggered);
436
437 qemu_clock_step(2000000 * 98);
438
439 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 98);
440 g_assert_true(triggered);
441
442 ptimer_stop(ptimer);
443 }
444
445 static void check_periodic_with_load_0(gconstpointer arg)
446 {
447 const uint8_t *policy = arg;
448 QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
449 ptimer_state *ptimer = ptimer_init(bh, *policy);
450
451 triggered = false;
452
453 ptimer_set_period(ptimer, 2000000);
454 ptimer_run(ptimer, 0);
455
456 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
457 g_assert_true(triggered);
458
459 triggered = false;
460
461 qemu_clock_step(2000000 + 100000);
462
463 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
464 g_assert_false(triggered);
465
466 ptimer_stop(ptimer);
467 }
468
469 static void check_oneshot_with_load_0(gconstpointer arg)
470 {
471 const uint8_t *policy = arg;
472 QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
473 ptimer_state *ptimer = ptimer_init(bh, *policy);
474
475 triggered = false;
476
477 ptimer_set_period(ptimer, 2000000);
478 ptimer_run(ptimer, 1);
479
480 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
481 g_assert_true(triggered);
482
483 triggered = false;
484
485 qemu_clock_step(2000000 + 100000);
486
487 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
488 g_assert_false(triggered);
489
490 triggered = false;
491
492 qemu_clock_step(2000000 + 100000);
493
494 g_assert_false(triggered);
495 }
496
497 static void add_ptimer_tests(uint8_t policy)
498 {
499 uint8_t *ppolicy = g_malloc(1);
500 char *policy_name = g_malloc(64);
501
502 *ppolicy = policy;
503
504 if (policy == PTIMER_POLICY_DEFAULT) {
505 g_sprintf(policy_name, "default");
506 }
507
508 qtest_add_data_func(
509 g_strdup_printf("/ptimer/set_count policy=%s", policy_name),
510 ppolicy, check_set_count);
511
512 qtest_add_data_func(
513 g_strdup_printf("/ptimer/set_limit policy=%s", policy_name),
514 ppolicy, check_set_limit);
515
516 qtest_add_data_func(
517 g_strdup_printf("/ptimer/oneshot policy=%s", policy_name),
518 ppolicy, check_oneshot);
519
520 qtest_add_data_func(
521 g_strdup_printf("/ptimer/periodic policy=%s", policy_name),
522 ppolicy, check_periodic);
523
524 qtest_add_data_func(
525 g_strdup_printf("/ptimer/on_the_fly_mode_change policy=%s", policy_name),
526 ppolicy, check_on_the_fly_mode_change);
527
528 qtest_add_data_func(
529 g_strdup_printf("/ptimer/on_the_fly_period_change policy=%s", policy_name),
530 ppolicy, check_on_the_fly_period_change);
531
532 qtest_add_data_func(
533 g_strdup_printf("/ptimer/on_the_fly_freq_change policy=%s", policy_name),
534 ppolicy, check_on_the_fly_freq_change);
535
536 qtest_add_data_func(
537 g_strdup_printf("/ptimer/run_with_period_0 policy=%s", policy_name),
538 ppolicy, check_run_with_period_0);
539
540 qtest_add_data_func(
541 g_strdup_printf("/ptimer/run_with_delta_0 policy=%s", policy_name),
542 ppolicy, check_run_with_delta_0);
543
544 qtest_add_data_func(
545 g_strdup_printf("/ptimer/periodic_with_load_0 policy=%s", policy_name),
546 ppolicy, check_periodic_with_load_0);
547
548 qtest_add_data_func(
549 g_strdup_printf("/ptimer/oneshot_with_load_0 policy=%s", policy_name),
550 ppolicy, check_oneshot_with_load_0);
551 }
552
553 int main(int argc, char **argv)
554 {
555 int i;
556
557 g_test_init(&argc, &argv, NULL);
558
559 for (i = 0; i < QEMU_CLOCK_MAX; i++) {
560 main_loop_tlg.tl[i] = g_new0(QEMUTimerList, 1);
561 }
562
563 add_ptimer_tests(PTIMER_POLICY_DEFAULT);
564
565 qtest_allowed = true;
566
567 return g_test_run();
568 }