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
);
194 ptimer_set_period(ptimer
, 2000000);
195 ptimer_set_limit(ptimer
, 10, 1);
196 ptimer_run(ptimer
, 0);
198 qemu_clock_step(2000000 * 10 + 100000);
200 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 9);
201 g_assert_true(triggered
);
205 qemu_clock_step(2000000);
207 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 8);
208 g_assert_false(triggered
);
210 ptimer_set_count(ptimer
, 20);
212 qemu_clock_step(2000000 * 11 + 100000);
214 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 8);
215 g_assert_false(triggered
);
217 qemu_clock_step(2000000 * 10);
219 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 8);
220 g_assert_true(triggered
);
225 qemu_clock_step(2000000);
227 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 8);
228 g_assert_false(triggered
);
230 ptimer_set_count(ptimer
, 3);
231 ptimer_run(ptimer
, 0);
233 qemu_clock_step(2000000 * 3 + 100000);
235 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 9);
236 g_assert_true(triggered
);
240 qemu_clock_step(2000000);
242 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 8);
243 g_assert_false(triggered
);
245 ptimer_set_count(ptimer
, 0);
246 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 10);
247 g_assert_true(triggered
);
251 qemu_clock_step(2000000 * 12 + 100000);
253 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 7);
254 g_assert_true(triggered
);
260 qemu_clock_step(2000000 * 12 + 100000);
262 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 7);
263 g_assert_false(triggered
);
265 ptimer_run(ptimer
, 0);
266 ptimer_set_period(ptimer
, 0);
268 qemu_clock_step(2000000 + 100000);
270 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 7);
271 g_assert_false(triggered
);
274 static void check_on_the_fly_mode_change(gconstpointer arg
)
276 const uint8_t *policy
= arg
;
277 QEMUBH
*bh
= qemu_bh_new(ptimer_trigger
, NULL
);
278 ptimer_state
*ptimer
= ptimer_init(bh
, *policy
);
282 ptimer_set_period(ptimer
, 2000000);
283 ptimer_set_limit(ptimer
, 10, 1);
284 ptimer_run(ptimer
, 1);
286 qemu_clock_step(2000000 * 9 + 100000);
288 ptimer_run(ptimer
, 0);
290 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
291 g_assert_false(triggered
);
293 qemu_clock_step(2000000);
295 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 9);
296 g_assert_true(triggered
);
300 qemu_clock_step(2000000 * 9);
302 ptimer_run(ptimer
, 1);
304 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
305 g_assert_false(triggered
);
307 qemu_clock_step(2000000 * 3);
309 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
310 g_assert_true(triggered
);
313 static void check_on_the_fly_period_change(gconstpointer arg
)
315 const uint8_t *policy
= arg
;
316 QEMUBH
*bh
= qemu_bh_new(ptimer_trigger
, NULL
);
317 ptimer_state
*ptimer
= ptimer_init(bh
, *policy
);
321 ptimer_set_period(ptimer
, 2000000);
322 ptimer_set_limit(ptimer
, 8, 1);
323 ptimer_run(ptimer
, 1);
325 qemu_clock_step(2000000 * 4 + 100000);
327 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 3);
328 g_assert_false(triggered
);
330 ptimer_set_period(ptimer
, 4000000);
331 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 3);
333 qemu_clock_step(4000000 * 2 + 100000);
335 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
336 g_assert_false(triggered
);
338 qemu_clock_step(4000000 * 2);
340 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
341 g_assert_true(triggered
);
344 static void check_on_the_fly_freq_change(gconstpointer arg
)
346 const uint8_t *policy
= arg
;
347 QEMUBH
*bh
= qemu_bh_new(ptimer_trigger
, NULL
);
348 ptimer_state
*ptimer
= ptimer_init(bh
, *policy
);
352 ptimer_set_freq(ptimer
, 500);
353 ptimer_set_limit(ptimer
, 8, 1);
354 ptimer_run(ptimer
, 1);
356 qemu_clock_step(2000000 * 4 + 100000);
358 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 3);
359 g_assert_false(triggered
);
361 ptimer_set_freq(ptimer
, 250);
362 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 3);
364 qemu_clock_step(2000000 * 4 + 100000);
366 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
367 g_assert_false(triggered
);
369 qemu_clock_step(2000000 * 4);
371 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
372 g_assert_true(triggered
);
375 static void check_run_with_period_0(gconstpointer arg
)
377 const uint8_t *policy
= arg
;
378 QEMUBH
*bh
= qemu_bh_new(ptimer_trigger
, NULL
);
379 ptimer_state
*ptimer
= ptimer_init(bh
, *policy
);
383 ptimer_set_count(ptimer
, 99);
384 ptimer_run(ptimer
, 1);
386 qemu_clock_step(10 * NANOSECONDS_PER_SECOND
);
388 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 99);
389 g_assert_false(triggered
);
392 static void check_run_with_delta_0(gconstpointer arg
)
394 const uint8_t *policy
= arg
;
395 QEMUBH
*bh
= qemu_bh_new(ptimer_trigger
, NULL
);
396 ptimer_state
*ptimer
= ptimer_init(bh
, *policy
);
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
);
408 qemu_clock_step(2000000 + 100000);
410 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 97);
411 g_assert_false(triggered
);
413 qemu_clock_step(2000000 * 97);
415 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
416 g_assert_false(triggered
);
418 qemu_clock_step(2000000 * 2);
420 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
421 g_assert_true(triggered
);
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
);
432 qemu_clock_step(2000000 + 100000);
434 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 97);
435 g_assert_false(triggered
);
437 qemu_clock_step(2000000 * 98);
439 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 98);
440 g_assert_true(triggered
);
445 static void check_periodic_with_load_0(gconstpointer arg
)
447 const uint8_t *policy
= arg
;
448 QEMUBH
*bh
= qemu_bh_new(ptimer_trigger
, NULL
);
449 ptimer_state
*ptimer
= ptimer_init(bh
, *policy
);
453 ptimer_set_period(ptimer
, 2000000);
454 ptimer_run(ptimer
, 0);
456 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
457 g_assert_true(triggered
);
461 qemu_clock_step(2000000 + 100000);
463 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
464 g_assert_false(triggered
);
469 static void check_oneshot_with_load_0(gconstpointer arg
)
471 const uint8_t *policy
= arg
;
472 QEMUBH
*bh
= qemu_bh_new(ptimer_trigger
, NULL
);
473 ptimer_state
*ptimer
= ptimer_init(bh
, *policy
);
477 ptimer_set_period(ptimer
, 2000000);
478 ptimer_run(ptimer
, 1);
480 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
481 g_assert_true(triggered
);
485 qemu_clock_step(2000000 + 100000);
487 g_assert_cmpuint(ptimer_get_count(ptimer
), ==, 0);
488 g_assert_false(triggered
);
492 qemu_clock_step(2000000 + 100000);
494 g_assert_false(triggered
);
497 static void add_ptimer_tests(uint8_t policy
)
499 uint8_t *ppolicy
= g_malloc(1);
500 char *policy_name
= g_malloc(64);
504 if (policy
== PTIMER_POLICY_DEFAULT
) {
505 g_sprintf(policy_name
, "default");
509 g_strdup_printf("/ptimer/set_count policy=%s", policy_name
),
510 ppolicy
, check_set_count
);
513 g_strdup_printf("/ptimer/set_limit policy=%s", policy_name
),
514 ppolicy
, check_set_limit
);
517 g_strdup_printf("/ptimer/oneshot policy=%s", policy_name
),
518 ppolicy
, check_oneshot
);
521 g_strdup_printf("/ptimer/periodic policy=%s", policy_name
),
522 ppolicy
, check_periodic
);
525 g_strdup_printf("/ptimer/on_the_fly_mode_change policy=%s", policy_name
),
526 ppolicy
, check_on_the_fly_mode_change
);
529 g_strdup_printf("/ptimer/on_the_fly_period_change policy=%s", policy_name
),
530 ppolicy
, check_on_the_fly_period_change
);
533 g_strdup_printf("/ptimer/on_the_fly_freq_change policy=%s", policy_name
),
534 ppolicy
, check_on_the_fly_freq_change
);
537 g_strdup_printf("/ptimer/run_with_period_0 policy=%s", policy_name
),
538 ppolicy
, check_run_with_period_0
);
541 g_strdup_printf("/ptimer/run_with_delta_0 policy=%s", policy_name
),
542 ppolicy
, check_run_with_delta_0
);
545 g_strdup_printf("/ptimer/periodic_with_load_0 policy=%s", policy_name
),
546 ppolicy
, check_periodic_with_load_0
);
549 g_strdup_printf("/ptimer/oneshot_with_load_0 policy=%s", policy_name
),
550 ppolicy
, check_oneshot_with_load_0
);
553 int main(int argc
, char **argv
)
557 g_test_init(&argc
, &argv
, NULL
);
559 for (i
= 0; i
< QEMU_CLOCK_MAX
; i
++) {
560 main_loop_tlg
.tl
[i
] = g_new0(QEMUTimerList
, 1);
563 add_ptimer_tests(PTIMER_POLICY_DEFAULT
);
565 qtest_allowed
= true;