xref: /qemu/tests/unit/ptimer-test.c (revision 293130aa91e9fc319beca1d8b1a9ac8c0cb33f75)
15b262bb6SDmitry Osipenko /*
25b262bb6SDmitry Osipenko  * QTest testcase for the ptimer
35b262bb6SDmitry Osipenko  *
45b262bb6SDmitry Osipenko  * Author: Dmitry Osipenko <digetx@gmail.com>
55b262bb6SDmitry Osipenko  *
65b262bb6SDmitry Osipenko  * This work is licensed under the terms of the GNU GPL, version 2 or later.
75b262bb6SDmitry Osipenko  * See the COPYING file in the top-level directory.
85b262bb6SDmitry Osipenko  *
95b262bb6SDmitry Osipenko  */
105b262bb6SDmitry Osipenko 
115b262bb6SDmitry Osipenko #include <glib/gprintf.h>
125b262bb6SDmitry Osipenko 
135b262bb6SDmitry Osipenko #include "qemu/osdep.h"
145b262bb6SDmitry Osipenko #include "qemu/main-loop.h"
155b262bb6SDmitry Osipenko #include "hw/ptimer.h"
165b262bb6SDmitry Osipenko 
175b262bb6SDmitry Osipenko #include "libqtest.h"
185b262bb6SDmitry Osipenko #include "ptimer-test.h"
195b262bb6SDmitry Osipenko 
205b262bb6SDmitry Osipenko static bool triggered;
215b262bb6SDmitry Osipenko 
225b262bb6SDmitry Osipenko static void ptimer_trigger(void *opaque)
235b262bb6SDmitry Osipenko {
245b262bb6SDmitry Osipenko     triggered = true;
255b262bb6SDmitry Osipenko }
265b262bb6SDmitry Osipenko 
275b262bb6SDmitry Osipenko static void ptimer_test_expire_qemu_timers(int64_t expire_time,
285b262bb6SDmitry Osipenko                                            QEMUClockType type)
295b262bb6SDmitry Osipenko {
305b262bb6SDmitry Osipenko     QEMUTimerList *timer_list = main_loop_tlg.tl[type];
315b262bb6SDmitry Osipenko     QEMUTimer *t = timer_list->active_timers.next;
325b262bb6SDmitry Osipenko 
335b262bb6SDmitry Osipenko     while (t != NULL) {
345b262bb6SDmitry Osipenko         if (t->expire_time == expire_time) {
355b262bb6SDmitry Osipenko             timer_del(t);
365b262bb6SDmitry Osipenko 
375b262bb6SDmitry Osipenko             if (t->cb != NULL) {
385b262bb6SDmitry Osipenko                 t->cb(t->opaque);
395b262bb6SDmitry Osipenko             }
405b262bb6SDmitry Osipenko         }
415b262bb6SDmitry Osipenko 
425b262bb6SDmitry Osipenko         t = t->next;
435b262bb6SDmitry Osipenko     }
445b262bb6SDmitry Osipenko }
455b262bb6SDmitry Osipenko 
465b262bb6SDmitry Osipenko static void ptimer_test_set_qemu_time_ns(int64_t ns)
475b262bb6SDmitry Osipenko {
485b262bb6SDmitry Osipenko     ptimer_test_time_ns = ns;
495b262bb6SDmitry Osipenko }
505b262bb6SDmitry Osipenko 
515b262bb6SDmitry Osipenko static void qemu_clock_step(uint64_t ns)
525b262bb6SDmitry Osipenko {
535b262bb6SDmitry Osipenko     int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
545b262bb6SDmitry Osipenko     int64_t advanced_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns;
555b262bb6SDmitry Osipenko 
565b262bb6SDmitry Osipenko     while (deadline != -1 && deadline <= advanced_time) {
575b262bb6SDmitry Osipenko         ptimer_test_set_qemu_time_ns(deadline);
585b262bb6SDmitry Osipenko         ptimer_test_expire_qemu_timers(deadline, QEMU_CLOCK_VIRTUAL);
595b262bb6SDmitry Osipenko         deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
605b262bb6SDmitry Osipenko     }
615b262bb6SDmitry Osipenko 
625b262bb6SDmitry Osipenko     ptimer_test_set_qemu_time_ns(advanced_time);
635b262bb6SDmitry Osipenko }
645b262bb6SDmitry Osipenko 
655b262bb6SDmitry Osipenko static void check_set_count(gconstpointer arg)
665b262bb6SDmitry Osipenko {
675b262bb6SDmitry Osipenko     const uint8_t *policy = arg;
685b262bb6SDmitry Osipenko     QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
695b262bb6SDmitry Osipenko     ptimer_state *ptimer = ptimer_init(bh, *policy);
705b262bb6SDmitry Osipenko 
715b262bb6SDmitry Osipenko     triggered = false;
725b262bb6SDmitry Osipenko 
735b262bb6SDmitry Osipenko     ptimer_set_count(ptimer, 1000);
745b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 1000);
755b262bb6SDmitry Osipenko     g_assert_false(triggered);
765b262bb6SDmitry Osipenko }
775b262bb6SDmitry Osipenko 
785b262bb6SDmitry Osipenko static void check_set_limit(gconstpointer arg)
795b262bb6SDmitry Osipenko {
805b262bb6SDmitry Osipenko     const uint8_t *policy = arg;
815b262bb6SDmitry Osipenko     QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
825b262bb6SDmitry Osipenko     ptimer_state *ptimer = ptimer_init(bh, *policy);
835b262bb6SDmitry Osipenko 
845b262bb6SDmitry Osipenko     triggered = false;
855b262bb6SDmitry Osipenko 
865b262bb6SDmitry Osipenko     ptimer_set_limit(ptimer, 1000, 0);
875b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
885b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_limit(ptimer), ==, 1000);
895b262bb6SDmitry Osipenko     g_assert_false(triggered);
905b262bb6SDmitry Osipenko 
915b262bb6SDmitry Osipenko     ptimer_set_limit(ptimer, 2000, 1);
925b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 2000);
935b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_limit(ptimer), ==, 2000);
945b262bb6SDmitry Osipenko     g_assert_false(triggered);
955b262bb6SDmitry Osipenko }
965b262bb6SDmitry Osipenko 
975b262bb6SDmitry Osipenko static void check_oneshot(gconstpointer arg)
985b262bb6SDmitry Osipenko {
995b262bb6SDmitry Osipenko     const uint8_t *policy = arg;
1005b262bb6SDmitry Osipenko     QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
1015b262bb6SDmitry Osipenko     ptimer_state *ptimer = ptimer_init(bh, *policy);
1025b262bb6SDmitry Osipenko 
1035b262bb6SDmitry Osipenko     triggered = false;
1045b262bb6SDmitry Osipenko 
1055b262bb6SDmitry Osipenko     ptimer_set_period(ptimer, 2000000);
1065b262bb6SDmitry Osipenko     ptimer_set_count(ptimer, 10);
1075b262bb6SDmitry Osipenko     ptimer_run(ptimer, 1);
1085b262bb6SDmitry Osipenko 
1095b262bb6SDmitry Osipenko     qemu_clock_step(2000000 * 2 + 100000);
1105b262bb6SDmitry Osipenko 
1115b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 7);
1125b262bb6SDmitry Osipenko     g_assert_false(triggered);
1135b262bb6SDmitry Osipenko 
1145b262bb6SDmitry Osipenko     ptimer_stop(ptimer);
1155b262bb6SDmitry Osipenko 
1165b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 7);
1175b262bb6SDmitry Osipenko     g_assert_false(triggered);
1185b262bb6SDmitry Osipenko 
1195b262bb6SDmitry Osipenko     qemu_clock_step(2000000 * 11);
1205b262bb6SDmitry Osipenko 
1215b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 7);
1225b262bb6SDmitry Osipenko     g_assert_false(triggered);
1235b262bb6SDmitry Osipenko 
1245b262bb6SDmitry Osipenko     ptimer_run(ptimer, 1);
1255b262bb6SDmitry Osipenko 
1265b262bb6SDmitry Osipenko     qemu_clock_step(2000000 * 7 + 100000);
1275b262bb6SDmitry Osipenko 
1285b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
1295b262bb6SDmitry Osipenko     g_assert_true(triggered);
1305b262bb6SDmitry Osipenko 
1315b262bb6SDmitry Osipenko     triggered = false;
1325b262bb6SDmitry Osipenko 
1335b262bb6SDmitry Osipenko     qemu_clock_step(2000000);
1345b262bb6SDmitry Osipenko 
1355b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
1365b262bb6SDmitry Osipenko     g_assert_false(triggered);
1375b262bb6SDmitry Osipenko 
1385b262bb6SDmitry Osipenko     qemu_clock_step(4000000);
1395b262bb6SDmitry Osipenko 
1405b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
1415b262bb6SDmitry Osipenko     g_assert_false(triggered);
1425b262bb6SDmitry Osipenko 
1435b262bb6SDmitry Osipenko     ptimer_set_count(ptimer, 10);
1445b262bb6SDmitry Osipenko 
1455b262bb6SDmitry Osipenko     qemu_clock_step(20000000 + 100000);
1465b262bb6SDmitry Osipenko 
1475b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
1485b262bb6SDmitry Osipenko     g_assert_false(triggered);
1495b262bb6SDmitry Osipenko 
1505b262bb6SDmitry Osipenko     ptimer_set_limit(ptimer, 9, 1);
1515b262bb6SDmitry Osipenko 
1525b262bb6SDmitry Osipenko     qemu_clock_step(20000000 + 100000);
1535b262bb6SDmitry Osipenko 
1545b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 9);
1555b262bb6SDmitry Osipenko     g_assert_false(triggered);
1565b262bb6SDmitry Osipenko 
1575b262bb6SDmitry Osipenko     ptimer_run(ptimer, 1);
1585b262bb6SDmitry Osipenko 
1595b262bb6SDmitry Osipenko     qemu_clock_step(2000000 + 100000);
1605b262bb6SDmitry Osipenko 
1615b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 7);
1625b262bb6SDmitry Osipenko     g_assert_false(triggered);
1635b262bb6SDmitry Osipenko 
1645b262bb6SDmitry Osipenko     ptimer_set_count(ptimer, 20);
1655b262bb6SDmitry Osipenko 
1665b262bb6SDmitry Osipenko     qemu_clock_step(2000000 * 19 + 100000);
1675b262bb6SDmitry Osipenko 
1685b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
1695b262bb6SDmitry Osipenko     g_assert_false(triggered);
1705b262bb6SDmitry Osipenko 
1715b262bb6SDmitry Osipenko     qemu_clock_step(2000000);
1725b262bb6SDmitry Osipenko 
1735b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
1745b262bb6SDmitry Osipenko     g_assert_true(triggered);
1755b262bb6SDmitry Osipenko 
1765b262bb6SDmitry Osipenko     ptimer_stop(ptimer);
1775b262bb6SDmitry Osipenko 
1785b262bb6SDmitry Osipenko     triggered = false;
1795b262bb6SDmitry Osipenko 
1805b262bb6SDmitry Osipenko     qemu_clock_step(2000000 * 12 + 100000);
1815b262bb6SDmitry Osipenko 
1825b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
1835b262bb6SDmitry Osipenko     g_assert_false(triggered);
1845b262bb6SDmitry Osipenko }
1855b262bb6SDmitry Osipenko 
1865b262bb6SDmitry Osipenko static void check_periodic(gconstpointer arg)
1875b262bb6SDmitry Osipenko {
1885b262bb6SDmitry Osipenko     const uint8_t *policy = arg;
1895b262bb6SDmitry Osipenko     QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
1905b262bb6SDmitry Osipenko     ptimer_state *ptimer = ptimer_init(bh, *policy);
191*293130aaSDmitry Osipenko     bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
1925b262bb6SDmitry Osipenko 
1935b262bb6SDmitry Osipenko     triggered = false;
1945b262bb6SDmitry Osipenko 
1955b262bb6SDmitry Osipenko     ptimer_set_period(ptimer, 2000000);
1965b262bb6SDmitry Osipenko     ptimer_set_limit(ptimer, 10, 1);
1975b262bb6SDmitry Osipenko     ptimer_run(ptimer, 0);
1985b262bb6SDmitry Osipenko 
199*293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
200*293130aaSDmitry Osipenko     g_assert_false(triggered);
201*293130aaSDmitry Osipenko 
202*293130aaSDmitry Osipenko     qemu_clock_step(100000);
2035b262bb6SDmitry Osipenko 
2045b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 9);
205*293130aaSDmitry Osipenko     g_assert_false(triggered);
206*293130aaSDmitry Osipenko 
207*293130aaSDmitry Osipenko     qemu_clock_step(2000000 * 10 - 100000);
208*293130aaSDmitry Osipenko 
209*293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, wrap_policy ? 0 : 10);
210*293130aaSDmitry Osipenko     g_assert_true(triggered);
211*293130aaSDmitry Osipenko 
212*293130aaSDmitry Osipenko     qemu_clock_step(100000);
213*293130aaSDmitry Osipenko 
214*293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, wrap_policy ? 0 : 9);
2155b262bb6SDmitry Osipenko     g_assert_true(triggered);
2165b262bb6SDmitry Osipenko 
2175b262bb6SDmitry Osipenko     triggered = false;
2185b262bb6SDmitry Osipenko 
2195b262bb6SDmitry Osipenko     qemu_clock_step(2000000);
2205b262bb6SDmitry Osipenko 
221*293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, wrap_policy ? 9 : 8);
2225b262bb6SDmitry Osipenko     g_assert_false(triggered);
2235b262bb6SDmitry Osipenko 
2245b262bb6SDmitry Osipenko     ptimer_set_count(ptimer, 20);
2255b262bb6SDmitry Osipenko 
226*293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 20);
227*293130aaSDmitry Osipenko     g_assert_false(triggered);
228*293130aaSDmitry Osipenko 
229*293130aaSDmitry Osipenko     qemu_clock_step(100000);
230*293130aaSDmitry Osipenko 
231*293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 19);
232*293130aaSDmitry Osipenko     g_assert_false(triggered);
233*293130aaSDmitry Osipenko 
2345b262bb6SDmitry Osipenko     qemu_clock_step(2000000 * 11 + 100000);
2355b262bb6SDmitry Osipenko 
2365b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 8);
2375b262bb6SDmitry Osipenko     g_assert_false(triggered);
2385b262bb6SDmitry Osipenko 
2395b262bb6SDmitry Osipenko     qemu_clock_step(2000000 * 10);
2405b262bb6SDmitry Osipenko 
241*293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, wrap_policy ? 9 : 8);
242*293130aaSDmitry Osipenko     g_assert_true(triggered);
243*293130aaSDmitry Osipenko 
244*293130aaSDmitry Osipenko     triggered = false;
245*293130aaSDmitry Osipenko 
246*293130aaSDmitry Osipenko     ptimer_set_count(ptimer, 3);
247*293130aaSDmitry Osipenko 
248*293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 3);
249*293130aaSDmitry Osipenko     g_assert_false(triggered);
250*293130aaSDmitry Osipenko 
251*293130aaSDmitry Osipenko     qemu_clock_step(100000);
252*293130aaSDmitry Osipenko 
253*293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 2);
254*293130aaSDmitry Osipenko     g_assert_false(triggered);
255*293130aaSDmitry Osipenko 
256*293130aaSDmitry Osipenko     qemu_clock_step(2000000 * 4);
257*293130aaSDmitry Osipenko 
258*293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, wrap_policy ? 9 : 8);
2595b262bb6SDmitry Osipenko     g_assert_true(triggered);
2605b262bb6SDmitry Osipenko 
2615b262bb6SDmitry Osipenko     ptimer_stop(ptimer);
2625b262bb6SDmitry Osipenko     triggered = false;
2635b262bb6SDmitry Osipenko 
2645b262bb6SDmitry Osipenko     qemu_clock_step(2000000);
2655b262bb6SDmitry Osipenko 
266*293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, wrap_policy ? 9 : 8);
2675b262bb6SDmitry Osipenko     g_assert_false(triggered);
2685b262bb6SDmitry Osipenko 
2695b262bb6SDmitry Osipenko     ptimer_set_count(ptimer, 3);
2705b262bb6SDmitry Osipenko     ptimer_run(ptimer, 0);
2715b262bb6SDmitry Osipenko 
2725b262bb6SDmitry Osipenko     qemu_clock_step(2000000 * 3 + 100000);
2735b262bb6SDmitry Osipenko 
274*293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, wrap_policy ? 0 : 9);
2755b262bb6SDmitry Osipenko     g_assert_true(triggered);
2765b262bb6SDmitry Osipenko 
2775b262bb6SDmitry Osipenko     triggered = false;
2785b262bb6SDmitry Osipenko 
2795b262bb6SDmitry Osipenko     qemu_clock_step(2000000);
2805b262bb6SDmitry Osipenko 
281*293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, wrap_policy ? 9 : 8);
2825b262bb6SDmitry Osipenko     g_assert_false(triggered);
2835b262bb6SDmitry Osipenko 
2845b262bb6SDmitry Osipenko     ptimer_set_count(ptimer, 0);
2855b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
2865b262bb6SDmitry Osipenko     g_assert_true(triggered);
2875b262bb6SDmitry Osipenko 
2885b262bb6SDmitry Osipenko     triggered = false;
2895b262bb6SDmitry Osipenko 
290*293130aaSDmitry Osipenko     qemu_clock_step(100000);
2915b262bb6SDmitry Osipenko 
292*293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 9);
293*293130aaSDmitry Osipenko     g_assert_false(triggered);
294*293130aaSDmitry Osipenko 
295*293130aaSDmitry Osipenko     qemu_clock_step(2000000 * 12);
296*293130aaSDmitry Osipenko 
297*293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, wrap_policy ? 8 : 7);
2985b262bb6SDmitry Osipenko     g_assert_true(triggered);
2995b262bb6SDmitry Osipenko 
3005b262bb6SDmitry Osipenko     ptimer_stop(ptimer);
3015b262bb6SDmitry Osipenko 
3025b262bb6SDmitry Osipenko     triggered = false;
3035b262bb6SDmitry Osipenko 
304*293130aaSDmitry Osipenko     qemu_clock_step(2000000 * 10);
3055b262bb6SDmitry Osipenko 
306*293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, wrap_policy ? 8 : 7);
3075b262bb6SDmitry Osipenko     g_assert_false(triggered);
3085b262bb6SDmitry Osipenko 
3095b262bb6SDmitry Osipenko     ptimer_run(ptimer, 0);
3105b262bb6SDmitry Osipenko     ptimer_set_period(ptimer, 0);
3115b262bb6SDmitry Osipenko 
3125b262bb6SDmitry Osipenko     qemu_clock_step(2000000 + 100000);
3135b262bb6SDmitry Osipenko 
314*293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, wrap_policy ? 8 : 7);
3155b262bb6SDmitry Osipenko     g_assert_false(triggered);
3165b262bb6SDmitry Osipenko }
3175b262bb6SDmitry Osipenko 
3185b262bb6SDmitry Osipenko static void check_on_the_fly_mode_change(gconstpointer arg)
3195b262bb6SDmitry Osipenko {
3205b262bb6SDmitry Osipenko     const uint8_t *policy = arg;
3215b262bb6SDmitry Osipenko     QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
3225b262bb6SDmitry Osipenko     ptimer_state *ptimer = ptimer_init(bh, *policy);
323*293130aaSDmitry Osipenko     bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
3245b262bb6SDmitry Osipenko 
3255b262bb6SDmitry Osipenko     triggered = false;
3265b262bb6SDmitry Osipenko 
3275b262bb6SDmitry Osipenko     ptimer_set_period(ptimer, 2000000);
3285b262bb6SDmitry Osipenko     ptimer_set_limit(ptimer, 10, 1);
3295b262bb6SDmitry Osipenko     ptimer_run(ptimer, 1);
3305b262bb6SDmitry Osipenko 
3315b262bb6SDmitry Osipenko     qemu_clock_step(2000000 * 9 + 100000);
3325b262bb6SDmitry Osipenko 
333*293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
334*293130aaSDmitry Osipenko     g_assert_false(triggered);
335*293130aaSDmitry Osipenko 
3365b262bb6SDmitry Osipenko     ptimer_run(ptimer, 0);
3375b262bb6SDmitry Osipenko 
3385b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
3395b262bb6SDmitry Osipenko     g_assert_false(triggered);
3405b262bb6SDmitry Osipenko 
3415b262bb6SDmitry Osipenko     qemu_clock_step(2000000);
3425b262bb6SDmitry Osipenko 
343*293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, wrap_policy ? 0 : 9);
3445b262bb6SDmitry Osipenko     g_assert_true(triggered);
3455b262bb6SDmitry Osipenko 
3465b262bb6SDmitry Osipenko     triggered = false;
3475b262bb6SDmitry Osipenko 
3485b262bb6SDmitry Osipenko     qemu_clock_step(2000000 * 9);
3495b262bb6SDmitry Osipenko 
3505b262bb6SDmitry Osipenko     ptimer_run(ptimer, 1);
3515b262bb6SDmitry Osipenko 
352*293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, wrap_policy ? 1 : 0);
3535b262bb6SDmitry Osipenko     g_assert_false(triggered);
3545b262bb6SDmitry Osipenko 
3555b262bb6SDmitry Osipenko     qemu_clock_step(2000000 * 3);
3565b262bb6SDmitry Osipenko 
3575b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
3585b262bb6SDmitry Osipenko     g_assert_true(triggered);
3595b262bb6SDmitry Osipenko }
3605b262bb6SDmitry Osipenko 
3615b262bb6SDmitry Osipenko static void check_on_the_fly_period_change(gconstpointer arg)
3625b262bb6SDmitry Osipenko {
3635b262bb6SDmitry Osipenko     const uint8_t *policy = arg;
3645b262bb6SDmitry Osipenko     QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
3655b262bb6SDmitry Osipenko     ptimer_state *ptimer = ptimer_init(bh, *policy);
3665b262bb6SDmitry Osipenko 
3675b262bb6SDmitry Osipenko     triggered = false;
3685b262bb6SDmitry Osipenko 
3695b262bb6SDmitry Osipenko     ptimer_set_period(ptimer, 2000000);
3705b262bb6SDmitry Osipenko     ptimer_set_limit(ptimer, 8, 1);
3715b262bb6SDmitry Osipenko     ptimer_run(ptimer, 1);
3725b262bb6SDmitry Osipenko 
3735b262bb6SDmitry Osipenko     qemu_clock_step(2000000 * 4 + 100000);
3745b262bb6SDmitry Osipenko 
3755b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 3);
3765b262bb6SDmitry Osipenko     g_assert_false(triggered);
3775b262bb6SDmitry Osipenko 
3785b262bb6SDmitry Osipenko     ptimer_set_period(ptimer, 4000000);
3795b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 3);
3805b262bb6SDmitry Osipenko 
3815b262bb6SDmitry Osipenko     qemu_clock_step(4000000 * 2 + 100000);
3825b262bb6SDmitry Osipenko 
3835b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
3845b262bb6SDmitry Osipenko     g_assert_false(triggered);
3855b262bb6SDmitry Osipenko 
3865b262bb6SDmitry Osipenko     qemu_clock_step(4000000 * 2);
3875b262bb6SDmitry Osipenko 
3885b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
3895b262bb6SDmitry Osipenko     g_assert_true(triggered);
3905b262bb6SDmitry Osipenko }
3915b262bb6SDmitry Osipenko 
3925b262bb6SDmitry Osipenko static void check_on_the_fly_freq_change(gconstpointer arg)
3935b262bb6SDmitry Osipenko {
3945b262bb6SDmitry Osipenko     const uint8_t *policy = arg;
3955b262bb6SDmitry Osipenko     QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
3965b262bb6SDmitry Osipenko     ptimer_state *ptimer = ptimer_init(bh, *policy);
3975b262bb6SDmitry Osipenko 
3985b262bb6SDmitry Osipenko     triggered = false;
3995b262bb6SDmitry Osipenko 
4005b262bb6SDmitry Osipenko     ptimer_set_freq(ptimer, 500);
4015b262bb6SDmitry Osipenko     ptimer_set_limit(ptimer, 8, 1);
4025b262bb6SDmitry Osipenko     ptimer_run(ptimer, 1);
4035b262bb6SDmitry Osipenko 
4045b262bb6SDmitry Osipenko     qemu_clock_step(2000000 * 4 + 100000);
4055b262bb6SDmitry Osipenko 
4065b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 3);
4075b262bb6SDmitry Osipenko     g_assert_false(triggered);
4085b262bb6SDmitry Osipenko 
4095b262bb6SDmitry Osipenko     ptimer_set_freq(ptimer, 250);
4105b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 3);
4115b262bb6SDmitry Osipenko 
4125b262bb6SDmitry Osipenko     qemu_clock_step(2000000 * 4 + 100000);
4135b262bb6SDmitry Osipenko 
4145b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
4155b262bb6SDmitry Osipenko     g_assert_false(triggered);
4165b262bb6SDmitry Osipenko 
4175b262bb6SDmitry Osipenko     qemu_clock_step(2000000 * 4);
4185b262bb6SDmitry Osipenko 
4195b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
4205b262bb6SDmitry Osipenko     g_assert_true(triggered);
4215b262bb6SDmitry Osipenko }
4225b262bb6SDmitry Osipenko 
4235b262bb6SDmitry Osipenko static void check_run_with_period_0(gconstpointer arg)
4245b262bb6SDmitry Osipenko {
4255b262bb6SDmitry Osipenko     const uint8_t *policy = arg;
4265b262bb6SDmitry Osipenko     QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
4275b262bb6SDmitry Osipenko     ptimer_state *ptimer = ptimer_init(bh, *policy);
4285b262bb6SDmitry Osipenko 
4295b262bb6SDmitry Osipenko     triggered = false;
4305b262bb6SDmitry Osipenko 
4315b262bb6SDmitry Osipenko     ptimer_set_count(ptimer, 99);
4325b262bb6SDmitry Osipenko     ptimer_run(ptimer, 1);
4335b262bb6SDmitry Osipenko 
4345b262bb6SDmitry Osipenko     qemu_clock_step(10 * NANOSECONDS_PER_SECOND);
4355b262bb6SDmitry Osipenko 
4365b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 99);
4375b262bb6SDmitry Osipenko     g_assert_false(triggered);
4385b262bb6SDmitry Osipenko }
4395b262bb6SDmitry Osipenko 
4405b262bb6SDmitry Osipenko static void check_run_with_delta_0(gconstpointer arg)
4415b262bb6SDmitry Osipenko {
4425b262bb6SDmitry Osipenko     const uint8_t *policy = arg;
4435b262bb6SDmitry Osipenko     QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
4445b262bb6SDmitry Osipenko     ptimer_state *ptimer = ptimer_init(bh, *policy);
445*293130aaSDmitry Osipenko     bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
4465b262bb6SDmitry Osipenko 
4475b262bb6SDmitry Osipenko     triggered = false;
4485b262bb6SDmitry Osipenko 
4495b262bb6SDmitry Osipenko     ptimer_set_period(ptimer, 2000000);
4505b262bb6SDmitry Osipenko     ptimer_set_limit(ptimer, 99, 0);
4515b262bb6SDmitry Osipenko     ptimer_run(ptimer, 1);
4525b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 99);
4535b262bb6SDmitry Osipenko     g_assert_true(triggered);
4545b262bb6SDmitry Osipenko 
4555b262bb6SDmitry Osipenko     triggered = false;
4565b262bb6SDmitry Osipenko 
4575b262bb6SDmitry Osipenko     qemu_clock_step(2000000 + 100000);
4585b262bb6SDmitry Osipenko 
4595b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 97);
4605b262bb6SDmitry Osipenko     g_assert_false(triggered);
4615b262bb6SDmitry Osipenko 
4625b262bb6SDmitry Osipenko     qemu_clock_step(2000000 * 97);
4635b262bb6SDmitry Osipenko 
4645b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
4655b262bb6SDmitry Osipenko     g_assert_false(triggered);
4665b262bb6SDmitry Osipenko 
4675b262bb6SDmitry Osipenko     qemu_clock_step(2000000 * 2);
4685b262bb6SDmitry Osipenko 
4695b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
4705b262bb6SDmitry Osipenko     g_assert_true(triggered);
4715b262bb6SDmitry Osipenko 
4725b262bb6SDmitry Osipenko     triggered = false;
4735b262bb6SDmitry Osipenko 
4745b262bb6SDmitry Osipenko     ptimer_set_count(ptimer, 0);
4755b262bb6SDmitry Osipenko     ptimer_run(ptimer, 0);
4765b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 99);
4775b262bb6SDmitry Osipenko     g_assert_true(triggered);
4785b262bb6SDmitry Osipenko 
4795b262bb6SDmitry Osipenko     triggered = false;
4805b262bb6SDmitry Osipenko 
481*293130aaSDmitry Osipenko     qemu_clock_step(100000);
482*293130aaSDmitry Osipenko 
483*293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 98);
484*293130aaSDmitry Osipenko     g_assert_false(triggered);
485*293130aaSDmitry Osipenko 
486*293130aaSDmitry Osipenko     triggered = false;
487*293130aaSDmitry Osipenko 
488*293130aaSDmitry Osipenko     qemu_clock_step(2000000);
4895b262bb6SDmitry Osipenko 
4905b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 97);
4915b262bb6SDmitry Osipenko     g_assert_false(triggered);
4925b262bb6SDmitry Osipenko 
4935b262bb6SDmitry Osipenko     qemu_clock_step(2000000 * 98);
4945b262bb6SDmitry Osipenko 
495*293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, wrap_policy ? 0 : 98);
4965b262bb6SDmitry Osipenko     g_assert_true(triggered);
4975b262bb6SDmitry Osipenko 
4985b262bb6SDmitry Osipenko     ptimer_stop(ptimer);
4995b262bb6SDmitry Osipenko }
5005b262bb6SDmitry Osipenko 
5015b262bb6SDmitry Osipenko static void check_periodic_with_load_0(gconstpointer arg)
5025b262bb6SDmitry Osipenko {
5035b262bb6SDmitry Osipenko     const uint8_t *policy = arg;
5045b262bb6SDmitry Osipenko     QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
5055b262bb6SDmitry Osipenko     ptimer_state *ptimer = ptimer_init(bh, *policy);
5065b262bb6SDmitry Osipenko 
5075b262bb6SDmitry Osipenko     triggered = false;
5085b262bb6SDmitry Osipenko 
5095b262bb6SDmitry Osipenko     ptimer_set_period(ptimer, 2000000);
5105b262bb6SDmitry Osipenko     ptimer_run(ptimer, 0);
5115b262bb6SDmitry Osipenko 
5125b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
5135b262bb6SDmitry Osipenko     g_assert_true(triggered);
5145b262bb6SDmitry Osipenko 
5155b262bb6SDmitry Osipenko     triggered = false;
5165b262bb6SDmitry Osipenko 
5175b262bb6SDmitry Osipenko     qemu_clock_step(2000000 + 100000);
5185b262bb6SDmitry Osipenko 
5195b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
5205b262bb6SDmitry Osipenko     g_assert_false(triggered);
5215b262bb6SDmitry Osipenko 
522*293130aaSDmitry Osipenko     triggered = false;
523*293130aaSDmitry Osipenko 
524*293130aaSDmitry Osipenko     ptimer_set_count(ptimer, 10);
525*293130aaSDmitry Osipenko     ptimer_run(ptimer, 0);
526*293130aaSDmitry Osipenko 
527*293130aaSDmitry Osipenko     qemu_clock_step(2000000 * 10 + 100000);
528*293130aaSDmitry Osipenko 
529*293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
530*293130aaSDmitry Osipenko     g_assert_true(triggered);
531*293130aaSDmitry Osipenko 
532*293130aaSDmitry Osipenko     triggered = false;
533*293130aaSDmitry Osipenko 
534*293130aaSDmitry Osipenko     qemu_clock_step(2000000 + 100000);
535*293130aaSDmitry Osipenko 
536*293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
537*293130aaSDmitry Osipenko     g_assert_false(triggered);
538*293130aaSDmitry Osipenko 
5395b262bb6SDmitry Osipenko     ptimer_stop(ptimer);
5405b262bb6SDmitry Osipenko }
5415b262bb6SDmitry Osipenko 
5425b262bb6SDmitry Osipenko static void check_oneshot_with_load_0(gconstpointer arg)
5435b262bb6SDmitry Osipenko {
5445b262bb6SDmitry Osipenko     const uint8_t *policy = arg;
5455b262bb6SDmitry Osipenko     QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
5465b262bb6SDmitry Osipenko     ptimer_state *ptimer = ptimer_init(bh, *policy);
5475b262bb6SDmitry Osipenko 
5485b262bb6SDmitry Osipenko     triggered = false;
5495b262bb6SDmitry Osipenko 
5505b262bb6SDmitry Osipenko     ptimer_set_period(ptimer, 2000000);
5515b262bb6SDmitry Osipenko     ptimer_run(ptimer, 1);
5525b262bb6SDmitry Osipenko 
5535b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
5545b262bb6SDmitry Osipenko     g_assert_true(triggered);
5555b262bb6SDmitry Osipenko 
5565b262bb6SDmitry Osipenko     triggered = false;
5575b262bb6SDmitry Osipenko 
5585b262bb6SDmitry Osipenko     qemu_clock_step(2000000 + 100000);
5595b262bb6SDmitry Osipenko 
5605b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
5615b262bb6SDmitry Osipenko     g_assert_false(triggered);
5625b262bb6SDmitry Osipenko }
5635b262bb6SDmitry Osipenko 
5645b262bb6SDmitry Osipenko static void add_ptimer_tests(uint8_t policy)
5655b262bb6SDmitry Osipenko {
5665b262bb6SDmitry Osipenko     uint8_t *ppolicy = g_malloc(1);
567*293130aaSDmitry Osipenko     char *policy_name = g_malloc0(256);
5685b262bb6SDmitry Osipenko 
5695b262bb6SDmitry Osipenko     *ppolicy = policy;
5705b262bb6SDmitry Osipenko 
5715b262bb6SDmitry Osipenko     if (policy == PTIMER_POLICY_DEFAULT) {
5725b262bb6SDmitry Osipenko         g_sprintf(policy_name, "default");
5735b262bb6SDmitry Osipenko     }
5745b262bb6SDmitry Osipenko 
575*293130aaSDmitry Osipenko     if (policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD) {
576*293130aaSDmitry Osipenko         g_strlcat(policy_name, "wrap_after_one_period,", 256);
577*293130aaSDmitry Osipenko     }
578*293130aaSDmitry Osipenko 
57924b94625SPaolo Bonzini     g_test_add_data_func(
5805b262bb6SDmitry Osipenko         g_strdup_printf("/ptimer/set_count policy=%s", policy_name),
5815b262bb6SDmitry Osipenko         ppolicy, check_set_count);
5825b262bb6SDmitry Osipenko 
58324b94625SPaolo Bonzini     g_test_add_data_func(
5845b262bb6SDmitry Osipenko         g_strdup_printf("/ptimer/set_limit policy=%s", policy_name),
5855b262bb6SDmitry Osipenko         ppolicy, check_set_limit);
5865b262bb6SDmitry Osipenko 
58724b94625SPaolo Bonzini     g_test_add_data_func(
5885b262bb6SDmitry Osipenko         g_strdup_printf("/ptimer/oneshot policy=%s", policy_name),
5895b262bb6SDmitry Osipenko         ppolicy, check_oneshot);
5905b262bb6SDmitry Osipenko 
59124b94625SPaolo Bonzini     g_test_add_data_func(
5925b262bb6SDmitry Osipenko         g_strdup_printf("/ptimer/periodic policy=%s", policy_name),
5935b262bb6SDmitry Osipenko         ppolicy, check_periodic);
5945b262bb6SDmitry Osipenko 
59524b94625SPaolo Bonzini     g_test_add_data_func(
5965b262bb6SDmitry Osipenko         g_strdup_printf("/ptimer/on_the_fly_mode_change policy=%s", policy_name),
5975b262bb6SDmitry Osipenko         ppolicy, check_on_the_fly_mode_change);
5985b262bb6SDmitry Osipenko 
59924b94625SPaolo Bonzini     g_test_add_data_func(
6005b262bb6SDmitry Osipenko         g_strdup_printf("/ptimer/on_the_fly_period_change policy=%s", policy_name),
6015b262bb6SDmitry Osipenko         ppolicy, check_on_the_fly_period_change);
6025b262bb6SDmitry Osipenko 
60324b94625SPaolo Bonzini     g_test_add_data_func(
6045b262bb6SDmitry Osipenko         g_strdup_printf("/ptimer/on_the_fly_freq_change policy=%s", policy_name),
6055b262bb6SDmitry Osipenko         ppolicy, check_on_the_fly_freq_change);
6065b262bb6SDmitry Osipenko 
60724b94625SPaolo Bonzini     g_test_add_data_func(
6085b262bb6SDmitry Osipenko         g_strdup_printf("/ptimer/run_with_period_0 policy=%s", policy_name),
6095b262bb6SDmitry Osipenko         ppolicy, check_run_with_period_0);
6105b262bb6SDmitry Osipenko 
61124b94625SPaolo Bonzini     g_test_add_data_func(
6125b262bb6SDmitry Osipenko         g_strdup_printf("/ptimer/run_with_delta_0 policy=%s", policy_name),
6135b262bb6SDmitry Osipenko         ppolicy, check_run_with_delta_0);
6145b262bb6SDmitry Osipenko 
61524b94625SPaolo Bonzini     g_test_add_data_func(
6165b262bb6SDmitry Osipenko         g_strdup_printf("/ptimer/periodic_with_load_0 policy=%s", policy_name),
6175b262bb6SDmitry Osipenko         ppolicy, check_periodic_with_load_0);
6185b262bb6SDmitry Osipenko 
61924b94625SPaolo Bonzini     g_test_add_data_func(
6205b262bb6SDmitry Osipenko         g_strdup_printf("/ptimer/oneshot_with_load_0 policy=%s", policy_name),
6215b262bb6SDmitry Osipenko         ppolicy, check_oneshot_with_load_0);
6225b262bb6SDmitry Osipenko }
6235b262bb6SDmitry Osipenko 
624*293130aaSDmitry Osipenko static void add_all_ptimer_policies_comb_tests(void)
625*293130aaSDmitry Osipenko {
626*293130aaSDmitry Osipenko     int last_policy = PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD;
627*293130aaSDmitry Osipenko     int policy = PTIMER_POLICY_DEFAULT;
628*293130aaSDmitry Osipenko 
629*293130aaSDmitry Osipenko     for (; policy < (last_policy << 1); policy++) {
630*293130aaSDmitry Osipenko         add_ptimer_tests(policy);
631*293130aaSDmitry Osipenko     }
632*293130aaSDmitry Osipenko }
633*293130aaSDmitry Osipenko 
6345b262bb6SDmitry Osipenko int main(int argc, char **argv)
6355b262bb6SDmitry Osipenko {
6365b262bb6SDmitry Osipenko     int i;
6375b262bb6SDmitry Osipenko 
6385b262bb6SDmitry Osipenko     g_test_init(&argc, &argv, NULL);
6395b262bb6SDmitry Osipenko 
6405b262bb6SDmitry Osipenko     for (i = 0; i < QEMU_CLOCK_MAX; i++) {
6415b262bb6SDmitry Osipenko         main_loop_tlg.tl[i] = g_new0(QEMUTimerList, 1);
6425b262bb6SDmitry Osipenko     }
6435b262bb6SDmitry Osipenko 
644*293130aaSDmitry Osipenko     add_all_ptimer_policies_comb_tests();
6455b262bb6SDmitry Osipenko 
6465b262bb6SDmitry Osipenko     qtest_allowed = true;
6475b262bb6SDmitry Osipenko 
6485b262bb6SDmitry Osipenko     return g_test_run();
6495b262bb6SDmitry Osipenko }
650