2 * QTest testcase for the ptimer
4 * Author: Dmitry Osipenko <digetx@gmail.com>
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.
11 #include <glib/gprintf.h>
13 #include "qemu/osdep.h"
14 #include "qemu/main-loop.h"
15 #include "hw/ptimer.h"
18 #include "ptimer-test.h"
20 static bool triggered
;
22 static void ptimer_trigger(void *opaque
)
27 static void ptimer_test_expire_qemu_timers(int64_t expire_time
,
30 QEMUTimerList
*timer_list
= main_loop_tlg
.tl
[type
];
31 QEMUTimer
*t
= timer_list
->active_timers
.next
;
34 if (t
->expire_time
== expire_time
) {
46 static void ptimer_test_set_qemu_time_ns(int64_t ns
)
48 ptimer_test_time_ns
= ns
;
51 static void qemu_clock_step(uint64_t ns
)
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
;
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
);
62 ptimer_test_set_qemu_time_ns(advanced_time
);
65 static void check_set_count(gconstpointer arg
)
67 const uint8_t *policy
= arg
;
68 QEMUBH
*bh
= qemu_bh_new(ptimer_trigger
, NULL
);
69 ptimer_state
*ptimer
= ptimer_init(bh
, *policy
);
73 ptimer_set_count(ptimer
, 1000);
74 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 1000);
75 g_assert_false(triggered
);
78 static void check_set_limit(gconstpointer arg
)
80 const uint8_t *policy
= arg
;
81 QEMUBH
*bh
= qemu_bh_new(ptimer_trigger
, NULL
);
82 ptimer_state
*ptimer
= ptimer_init(bh
, *policy
);
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
);
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
);
97 static void check_oneshot(gconstpointer arg
)
99 const uint8_t *policy
= arg
;
100 QEMUBH
*bh
= qemu_bh_new(ptimer_trigger
, NULL
);
101 ptimer_state
*ptimer
= ptimer_init(bh
, *policy
);
105 ptimer_set_period(ptimer
, 2000000);
106 ptimer_set_count(ptimer
, 10);
107 ptimer_run(ptimer
, 1);
109 qemu_clock_step(2000000 * 2 + 100000);
111 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 7);
112 g_assert_false(triggered
);
116 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 7);
117 g_assert_false(triggered
);
119 qemu_clock_step(2000000 * 11);
121 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 7);
122 g_assert_false(triggered
);
124 ptimer_run(ptimer
, 1);
126 qemu_clock_step(2000000 * 7 + 100000);
128 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
129 g_assert_true(triggered
);
133 qemu_clock_step(2000000);
135 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
136 g_assert_false(triggered
);
138 qemu_clock_step(4000000);
140 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
141 g_assert_false(triggered
);
143 ptimer_set_count(ptimer
, 10);
145 qemu_clock_step(20000000 + 100000);
147 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 10);
148 g_assert_false(triggered
);
150 ptimer_set_limit(ptimer
, 9, 1);
152 qemu_clock_step(20000000 + 100000);
154 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 9);
155 g_assert_false(triggered
);
157 ptimer_run(ptimer
, 1);
159 qemu_clock_step(2000000 + 100000);
161 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 7);
162 g_assert_false(triggered
);
164 ptimer_set_count(ptimer
, 20);
166 qemu_clock_step(2000000 * 19 + 100000);
168 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
169 g_assert_false(triggered
);
171 qemu_clock_step(2000000);
173 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
174 g_assert_true(triggered
);
180 qemu_clock_step(2000000 * 12 + 100000);
182 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
183 g_assert_false(triggered
);
186 static void check_periodic(gconstpointer arg
)
188 const uint8_t *policy
= arg
;
189 QEMUBH
*bh
= qemu_bh_new(ptimer_trigger
, NULL
);
190 ptimer_state
*ptimer
= ptimer_init(bh
, *policy
);
191 bool wrap_policy
= (*policy
& PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD
);
192 bool no_immediate_trigger
= (*policy
& PTIMER_POLICY_NO_IMMEDIATE_TRIGGER
);
196 ptimer_set_period(ptimer
, 2000000);
197 ptimer_set_limit(ptimer
, 10, 1);
198 ptimer_run(ptimer
, 0);
200 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 10);
201 g_assert_false(triggered
);
203 qemu_clock_step(100000);
205 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 9);
206 g_assert_false(triggered
);
208 qemu_clock_step(2000000 * 10 - 100000);
210 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, wrap_policy
? 0 : 10);
211 g_assert_true(triggered
);
213 qemu_clock_step(100000);
215 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, wrap_policy
? 0 : 9);
216 g_assert_true(triggered
);
220 qemu_clock_step(2000000);
222 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, wrap_policy
? 9 : 8);
223 g_assert_false(triggered
);
225 ptimer_set_count(ptimer
, 20);
227 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 20);
228 g_assert_false(triggered
);
230 qemu_clock_step(100000);
232 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 19);
233 g_assert_false(triggered
);
235 qemu_clock_step(2000000 * 11 + 100000);
237 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 8);
238 g_assert_false(triggered
);
240 qemu_clock_step(2000000 * 10);
242 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, wrap_policy
? 9 : 8);
243 g_assert_true(triggered
);
247 ptimer_set_count(ptimer
, 3);
249 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 3);
250 g_assert_false(triggered
);
252 qemu_clock_step(100000);
254 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 2);
255 g_assert_false(triggered
);
257 qemu_clock_step(2000000 * 4);
259 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, wrap_policy
? 9 : 8);
260 g_assert_true(triggered
);
265 qemu_clock_step(2000000);
267 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, wrap_policy
? 9 : 8);
268 g_assert_false(triggered
);
270 ptimer_set_count(ptimer
, 3);
271 ptimer_run(ptimer
, 0);
273 qemu_clock_step(2000000 * 3 + 100000);
275 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, wrap_policy
? 0 : 9);
276 g_assert_true(triggered
);
280 qemu_clock_step(2000000);
282 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, wrap_policy
? 9 : 8);
283 g_assert_false(triggered
);
285 ptimer_set_count(ptimer
, 0);
286 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 10);
288 if (no_immediate_trigger
) {
289 g_assert_false(triggered
);
291 g_assert_true(triggered
);
296 qemu_clock_step(100000);
298 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 9);
299 g_assert_false(triggered
);
301 qemu_clock_step(2000000 * 12);
303 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, wrap_policy
? 8 : 7);
304 g_assert_true(triggered
);
310 qemu_clock_step(2000000 * 10);
312 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, wrap_policy
? 8 : 7);
313 g_assert_false(triggered
);
315 ptimer_run(ptimer
, 0);
316 ptimer_set_period(ptimer
, 0);
318 qemu_clock_step(2000000 + 100000);
320 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, wrap_policy
? 8 : 7);
321 g_assert_false(triggered
);
324 static void check_on_the_fly_mode_change(gconstpointer arg
)
326 const uint8_t *policy
= arg
;
327 QEMUBH
*bh
= qemu_bh_new(ptimer_trigger
, NULL
);
328 ptimer_state
*ptimer
= ptimer_init(bh
, *policy
);
329 bool wrap_policy
= (*policy
& PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD
);
333 ptimer_set_period(ptimer
, 2000000);
334 ptimer_set_limit(ptimer
, 10, 1);
335 ptimer_run(ptimer
, 1);
337 qemu_clock_step(2000000 * 9 + 100000);
339 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
340 g_assert_false(triggered
);
342 ptimer_run(ptimer
, 0);
344 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
345 g_assert_false(triggered
);
347 qemu_clock_step(2000000);
349 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, wrap_policy
? 0 : 9);
350 g_assert_true(triggered
);
354 qemu_clock_step(2000000 * 9);
356 ptimer_run(ptimer
, 1);
358 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, wrap_policy
? 1 : 0);
359 g_assert_false(triggered
);
361 qemu_clock_step(2000000 * 3);
363 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
364 g_assert_true(triggered
);
367 static void check_on_the_fly_period_change(gconstpointer arg
)
369 const uint8_t *policy
= arg
;
370 QEMUBH
*bh
= qemu_bh_new(ptimer_trigger
, NULL
);
371 ptimer_state
*ptimer
= ptimer_init(bh
, *policy
);
375 ptimer_set_period(ptimer
, 2000000);
376 ptimer_set_limit(ptimer
, 8, 1);
377 ptimer_run(ptimer
, 1);
379 qemu_clock_step(2000000 * 4 + 100000);
381 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 3);
382 g_assert_false(triggered
);
384 ptimer_set_period(ptimer
, 4000000);
385 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 3);
387 qemu_clock_step(4000000 * 2 + 100000);
389 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
390 g_assert_false(triggered
);
392 qemu_clock_step(4000000 * 2);
394 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
395 g_assert_true(triggered
);
398 static void check_on_the_fly_freq_change(gconstpointer arg
)
400 const uint8_t *policy
= arg
;
401 QEMUBH
*bh
= qemu_bh_new(ptimer_trigger
, NULL
);
402 ptimer_state
*ptimer
= ptimer_init(bh
, *policy
);
406 ptimer_set_freq(ptimer
, 500);
407 ptimer_set_limit(ptimer
, 8, 1);
408 ptimer_run(ptimer
, 1);
410 qemu_clock_step(2000000 * 4 + 100000);
412 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 3);
413 g_assert_false(triggered
);
415 ptimer_set_freq(ptimer
, 250);
416 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 3);
418 qemu_clock_step(2000000 * 4 + 100000);
420 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
421 g_assert_false(triggered
);
423 qemu_clock_step(2000000 * 4);
425 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
426 g_assert_true(triggered
);
429 static void check_run_with_period_0(gconstpointer arg
)
431 const uint8_t *policy
= arg
;
432 QEMUBH
*bh
= qemu_bh_new(ptimer_trigger
, NULL
);
433 ptimer_state
*ptimer
= ptimer_init(bh
, *policy
);
437 ptimer_set_count(ptimer
, 99);
438 ptimer_run(ptimer
, 1);
440 qemu_clock_step(10 * NANOSECONDS_PER_SECOND
);
442 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 99);
443 g_assert_false(triggered
);
446 static void check_run_with_delta_0(gconstpointer arg
)
448 const uint8_t *policy
= arg
;
449 QEMUBH
*bh
= qemu_bh_new(ptimer_trigger
, NULL
);
450 ptimer_state
*ptimer
= ptimer_init(bh
, *policy
);
451 bool wrap_policy
= (*policy
& PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD
);
452 bool no_immediate_trigger
= (*policy
& PTIMER_POLICY_NO_IMMEDIATE_TRIGGER
);
456 ptimer_set_period(ptimer
, 2000000);
457 ptimer_set_limit(ptimer
, 99, 0);
458 ptimer_run(ptimer
, 1);
459 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 99);
461 if (no_immediate_trigger
) {
462 g_assert_false(triggered
);
464 g_assert_true(triggered
);
469 if (no_immediate_trigger
) {
470 qemu_clock_step(2000000 + 100000);
472 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 97);
473 g_assert_false(triggered
);
475 ptimer_set_count(ptimer
, 99);
476 ptimer_run(ptimer
, 1);
479 qemu_clock_step(2000000 + 100000);
481 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 97);
482 g_assert_false(triggered
);
484 qemu_clock_step(2000000 * 97);
486 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
487 g_assert_false(triggered
);
489 qemu_clock_step(2000000 * 2);
491 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
492 g_assert_true(triggered
);
496 ptimer_set_count(ptimer
, 0);
497 ptimer_run(ptimer
, 0);
498 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 99);
500 if (no_immediate_trigger
) {
501 g_assert_false(triggered
);
503 g_assert_true(triggered
);
508 qemu_clock_step(100000);
510 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 98);
511 g_assert_false(triggered
);
515 qemu_clock_step(2000000);
517 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 97);
518 g_assert_false(triggered
);
520 qemu_clock_step(2000000 * 98);
522 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, wrap_policy
? 0 : 98);
523 g_assert_true(triggered
);
528 static void check_periodic_with_load_0(gconstpointer arg
)
530 const uint8_t *policy
= arg
;
531 QEMUBH
*bh
= qemu_bh_new(ptimer_trigger
, NULL
);
532 ptimer_state
*ptimer
= ptimer_init(bh
, *policy
);
533 bool continuous_trigger
= (*policy
& PTIMER_POLICY_CONTINUOUS_TRIGGER
);
534 bool no_immediate_trigger
= (*policy
& PTIMER_POLICY_NO_IMMEDIATE_TRIGGER
);
538 ptimer_set_period(ptimer
, 2000000);
539 ptimer_run(ptimer
, 0);
541 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
543 if (no_immediate_trigger
) {
544 g_assert_false(triggered
);
546 g_assert_true(triggered
);
551 qemu_clock_step(2000000 + 100000);
553 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
555 if (continuous_trigger
|| no_immediate_trigger
) {
556 g_assert_true(triggered
);
558 g_assert_false(triggered
);
563 ptimer_set_count(ptimer
, 10);
564 ptimer_run(ptimer
, 0);
566 qemu_clock_step(2000000 * 10 + 100000);
568 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
569 g_assert_true(triggered
);
573 qemu_clock_step(2000000 + 100000);
575 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
577 if (continuous_trigger
) {
578 g_assert_true(triggered
);
580 g_assert_false(triggered
);
586 static void check_oneshot_with_load_0(gconstpointer arg
)
588 const uint8_t *policy
= arg
;
589 QEMUBH
*bh
= qemu_bh_new(ptimer_trigger
, NULL
);
590 ptimer_state
*ptimer
= ptimer_init(bh
, *policy
);
591 bool no_immediate_trigger
= (*policy
& PTIMER_POLICY_NO_IMMEDIATE_TRIGGER
);
595 ptimer_set_period(ptimer
, 2000000);
596 ptimer_run(ptimer
, 1);
598 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
600 if (no_immediate_trigger
) {
601 g_assert_false(triggered
);
603 g_assert_true(triggered
);
608 qemu_clock_step(2000000 + 100000);
610 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
612 if (no_immediate_trigger
) {
613 g_assert_true(triggered
);
615 g_assert_false(triggered
);
619 static void add_ptimer_tests(uint8_t policy
)
621 uint8_t *ppolicy
= g_malloc(1);
622 char *policy_name
= g_malloc0(256);
626 if (policy
== PTIMER_POLICY_DEFAULT
) {
627 g_sprintf(policy_name
, "default");
630 if (policy
& PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD
) {
631 g_strlcat(policy_name
, "wrap_after_one_period,", 256);
634 if (policy
& PTIMER_POLICY_CONTINUOUS_TRIGGER
) {
635 g_strlcat(policy_name
, "continuous_trigger,", 256);
638 if (policy
& PTIMER_POLICY_NO_IMMEDIATE_TRIGGER
) {
639 g_strlcat(policy_name
, "no_immediate_trigger,", 256);
642 g_test_add_data_func(
643 g_strdup_printf("/ptimer/set_count policy=%s", policy_name
),
644 ppolicy
, check_set_count
);
646 g_test_add_data_func(
647 g_strdup_printf("/ptimer/set_limit policy=%s", policy_name
),
648 ppolicy
, check_set_limit
);
650 g_test_add_data_func(
651 g_strdup_printf("/ptimer/oneshot policy=%s", policy_name
),
652 ppolicy
, check_oneshot
);
654 g_test_add_data_func(
655 g_strdup_printf("/ptimer/periodic policy=%s", policy_name
),
656 ppolicy
, check_periodic
);
658 g_test_add_data_func(
659 g_strdup_printf("/ptimer/on_the_fly_mode_change policy=%s", policy_name
),
660 ppolicy
, check_on_the_fly_mode_change
);
662 g_test_add_data_func(
663 g_strdup_printf("/ptimer/on_the_fly_period_change policy=%s", policy_name
),
664 ppolicy
, check_on_the_fly_period_change
);
666 g_test_add_data_func(
667 g_strdup_printf("/ptimer/on_the_fly_freq_change policy=%s", policy_name
),
668 ppolicy
, check_on_the_fly_freq_change
);
670 g_test_add_data_func(
671 g_strdup_printf("/ptimer/run_with_period_0 policy=%s", policy_name
),
672 ppolicy
, check_run_with_period_0
);
674 g_test_add_data_func(
675 g_strdup_printf("/ptimer/run_with_delta_0 policy=%s", policy_name
),
676 ppolicy
, check_run_with_delta_0
);
678 g_test_add_data_func(
679 g_strdup_printf("/ptimer/periodic_with_load_0 policy=%s", policy_name
),
680 ppolicy
, check_periodic_with_load_0
);
682 g_test_add_data_func(
683 g_strdup_printf("/ptimer/oneshot_with_load_0 policy=%s", policy_name
),
684 ppolicy
, check_oneshot_with_load_0
);
687 static void add_all_ptimer_policies_comb_tests(void)
689 int last_policy
= PTIMER_POLICY_NO_IMMEDIATE_TRIGGER
;
690 int policy
= PTIMER_POLICY_DEFAULT
;
692 for (; policy
< (last_policy
<< 1); policy
++) {
693 add_ptimer_tests(policy
);
697 int main(int argc
, char **argv
)
701 g_test_init(&argc
, &argv
, NULL
);
703 for (i
= 0; i
< QEMU_CLOCK_MAX
; i
++) {
704 main_loop_tlg
.tl
[i
] = g_new0(QEMUTimerList
, 1);
707 add_all_ptimer_policies_comb_tests();
709 qtest_allowed
= true;