xref: /qemu/tests/unit/ptimer-test.c (revision 2e74583b29fff8e0e543898a9c61508a213ad83e)
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);
191293130aaSDmitry 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 
199293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
200293130aaSDmitry Osipenko     g_assert_false(triggered);
201293130aaSDmitry Osipenko 
202293130aaSDmitry Osipenko     qemu_clock_step(100000);
2035b262bb6SDmitry Osipenko 
2045b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 9);
205293130aaSDmitry Osipenko     g_assert_false(triggered);
206293130aaSDmitry Osipenko 
207293130aaSDmitry Osipenko     qemu_clock_step(2000000 * 10 - 100000);
208293130aaSDmitry Osipenko 
209293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, wrap_policy ? 0 : 10);
210293130aaSDmitry Osipenko     g_assert_true(triggered);
211293130aaSDmitry Osipenko 
212293130aaSDmitry Osipenko     qemu_clock_step(100000);
213293130aaSDmitry Osipenko 
214293130aaSDmitry 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 
221293130aaSDmitry 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 
226293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 20);
227293130aaSDmitry Osipenko     g_assert_false(triggered);
228293130aaSDmitry Osipenko 
229293130aaSDmitry Osipenko     qemu_clock_step(100000);
230293130aaSDmitry Osipenko 
231293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 19);
232293130aaSDmitry Osipenko     g_assert_false(triggered);
233293130aaSDmitry 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 
241293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, wrap_policy ? 9 : 8);
242293130aaSDmitry Osipenko     g_assert_true(triggered);
243293130aaSDmitry Osipenko 
244293130aaSDmitry Osipenko     triggered = false;
245293130aaSDmitry Osipenko 
246293130aaSDmitry Osipenko     ptimer_set_count(ptimer, 3);
247293130aaSDmitry Osipenko 
248293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 3);
249293130aaSDmitry Osipenko     g_assert_false(triggered);
250293130aaSDmitry Osipenko 
251293130aaSDmitry Osipenko     qemu_clock_step(100000);
252293130aaSDmitry Osipenko 
253293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 2);
254293130aaSDmitry Osipenko     g_assert_false(triggered);
255293130aaSDmitry Osipenko 
256293130aaSDmitry Osipenko     qemu_clock_step(2000000 * 4);
257293130aaSDmitry Osipenko 
258293130aaSDmitry 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 
266293130aaSDmitry 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 
274293130aaSDmitry 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 
281293130aaSDmitry 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 
290293130aaSDmitry Osipenko     qemu_clock_step(100000);
2915b262bb6SDmitry Osipenko 
292293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 9);
293293130aaSDmitry Osipenko     g_assert_false(triggered);
294293130aaSDmitry Osipenko 
295293130aaSDmitry Osipenko     qemu_clock_step(2000000 * 12);
296293130aaSDmitry Osipenko 
297293130aaSDmitry 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 
304293130aaSDmitry Osipenko     qemu_clock_step(2000000 * 10);
3055b262bb6SDmitry Osipenko 
306293130aaSDmitry 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 
314293130aaSDmitry 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);
323293130aaSDmitry 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 
333293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
334293130aaSDmitry Osipenko     g_assert_false(triggered);
335293130aaSDmitry 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 
343293130aaSDmitry 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 
352293130aaSDmitry 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);
445293130aaSDmitry 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 
481293130aaSDmitry Osipenko     qemu_clock_step(100000);
482293130aaSDmitry Osipenko 
483293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 98);
484293130aaSDmitry Osipenko     g_assert_false(triggered);
485293130aaSDmitry Osipenko 
486293130aaSDmitry Osipenko     triggered = false;
487293130aaSDmitry Osipenko 
488293130aaSDmitry 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 
495293130aaSDmitry 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);
506*2e74583bSDmitry Osipenko     bool continuous_trigger = (*policy & PTIMER_POLICY_CONTINUOUS_TRIGGER);
5075b262bb6SDmitry Osipenko 
5085b262bb6SDmitry Osipenko     triggered = false;
5095b262bb6SDmitry Osipenko 
5105b262bb6SDmitry Osipenko     ptimer_set_period(ptimer, 2000000);
5115b262bb6SDmitry Osipenko     ptimer_run(ptimer, 0);
5125b262bb6SDmitry Osipenko 
5135b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
5145b262bb6SDmitry Osipenko     g_assert_true(triggered);
5155b262bb6SDmitry Osipenko 
5165b262bb6SDmitry Osipenko     triggered = false;
5175b262bb6SDmitry Osipenko 
5185b262bb6SDmitry Osipenko     qemu_clock_step(2000000 + 100000);
5195b262bb6SDmitry Osipenko 
5205b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
521*2e74583bSDmitry Osipenko 
522*2e74583bSDmitry Osipenko     if (continuous_trigger) {
523*2e74583bSDmitry Osipenko         g_assert_true(triggered);
524*2e74583bSDmitry Osipenko     } else {
5255b262bb6SDmitry Osipenko         g_assert_false(triggered);
526*2e74583bSDmitry Osipenko     }
5275b262bb6SDmitry Osipenko 
528293130aaSDmitry Osipenko     triggered = false;
529293130aaSDmitry Osipenko 
530293130aaSDmitry Osipenko     ptimer_set_count(ptimer, 10);
531293130aaSDmitry Osipenko     ptimer_run(ptimer, 0);
532293130aaSDmitry Osipenko 
533293130aaSDmitry Osipenko     qemu_clock_step(2000000 * 10 + 100000);
534293130aaSDmitry Osipenko 
535293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
536293130aaSDmitry Osipenko     g_assert_true(triggered);
537293130aaSDmitry Osipenko 
538293130aaSDmitry Osipenko     triggered = false;
539293130aaSDmitry Osipenko 
540293130aaSDmitry Osipenko     qemu_clock_step(2000000 + 100000);
541293130aaSDmitry Osipenko 
542293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
543*2e74583bSDmitry Osipenko 
544*2e74583bSDmitry Osipenko     if (continuous_trigger) {
545*2e74583bSDmitry Osipenko         g_assert_true(triggered);
546*2e74583bSDmitry Osipenko     } else {
547293130aaSDmitry Osipenko         g_assert_false(triggered);
548*2e74583bSDmitry Osipenko     }
549293130aaSDmitry Osipenko 
5505b262bb6SDmitry Osipenko     ptimer_stop(ptimer);
5515b262bb6SDmitry Osipenko }
5525b262bb6SDmitry Osipenko 
5535b262bb6SDmitry Osipenko static void check_oneshot_with_load_0(gconstpointer arg)
5545b262bb6SDmitry Osipenko {
5555b262bb6SDmitry Osipenko     const uint8_t *policy = arg;
5565b262bb6SDmitry Osipenko     QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
5575b262bb6SDmitry Osipenko     ptimer_state *ptimer = ptimer_init(bh, *policy);
5585b262bb6SDmitry Osipenko 
5595b262bb6SDmitry Osipenko     triggered = false;
5605b262bb6SDmitry Osipenko 
5615b262bb6SDmitry Osipenko     ptimer_set_period(ptimer, 2000000);
5625b262bb6SDmitry Osipenko     ptimer_run(ptimer, 1);
5635b262bb6SDmitry Osipenko 
5645b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
5655b262bb6SDmitry Osipenko     g_assert_true(triggered);
5665b262bb6SDmitry Osipenko 
5675b262bb6SDmitry Osipenko     triggered = false;
5685b262bb6SDmitry Osipenko 
5695b262bb6SDmitry Osipenko     qemu_clock_step(2000000 + 100000);
5705b262bb6SDmitry Osipenko 
5715b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
5725b262bb6SDmitry Osipenko     g_assert_false(triggered);
5735b262bb6SDmitry Osipenko }
5745b262bb6SDmitry Osipenko 
5755b262bb6SDmitry Osipenko static void add_ptimer_tests(uint8_t policy)
5765b262bb6SDmitry Osipenko {
5775b262bb6SDmitry Osipenko     uint8_t *ppolicy = g_malloc(1);
578293130aaSDmitry Osipenko     char *policy_name = g_malloc0(256);
5795b262bb6SDmitry Osipenko 
5805b262bb6SDmitry Osipenko     *ppolicy = policy;
5815b262bb6SDmitry Osipenko 
5825b262bb6SDmitry Osipenko     if (policy == PTIMER_POLICY_DEFAULT) {
5835b262bb6SDmitry Osipenko         g_sprintf(policy_name, "default");
5845b262bb6SDmitry Osipenko     }
5855b262bb6SDmitry Osipenko 
586293130aaSDmitry Osipenko     if (policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD) {
587293130aaSDmitry Osipenko         g_strlcat(policy_name, "wrap_after_one_period,", 256);
588293130aaSDmitry Osipenko     }
589293130aaSDmitry Osipenko 
590*2e74583bSDmitry Osipenko     if (policy & PTIMER_POLICY_CONTINUOUS_TRIGGER) {
591*2e74583bSDmitry Osipenko         g_strlcat(policy_name, "continuous_trigger,", 256);
592*2e74583bSDmitry Osipenko     }
593*2e74583bSDmitry Osipenko 
59424b94625SPaolo Bonzini     g_test_add_data_func(
5955b262bb6SDmitry Osipenko         g_strdup_printf("/ptimer/set_count policy=%s", policy_name),
5965b262bb6SDmitry Osipenko         ppolicy, check_set_count);
5975b262bb6SDmitry Osipenko 
59824b94625SPaolo Bonzini     g_test_add_data_func(
5995b262bb6SDmitry Osipenko         g_strdup_printf("/ptimer/set_limit policy=%s", policy_name),
6005b262bb6SDmitry Osipenko         ppolicy, check_set_limit);
6015b262bb6SDmitry Osipenko 
60224b94625SPaolo Bonzini     g_test_add_data_func(
6035b262bb6SDmitry Osipenko         g_strdup_printf("/ptimer/oneshot policy=%s", policy_name),
6045b262bb6SDmitry Osipenko         ppolicy, check_oneshot);
6055b262bb6SDmitry Osipenko 
60624b94625SPaolo Bonzini     g_test_add_data_func(
6075b262bb6SDmitry Osipenko         g_strdup_printf("/ptimer/periodic policy=%s", policy_name),
6085b262bb6SDmitry Osipenko         ppolicy, check_periodic);
6095b262bb6SDmitry Osipenko 
61024b94625SPaolo Bonzini     g_test_add_data_func(
6115b262bb6SDmitry Osipenko         g_strdup_printf("/ptimer/on_the_fly_mode_change policy=%s", policy_name),
6125b262bb6SDmitry Osipenko         ppolicy, check_on_the_fly_mode_change);
6135b262bb6SDmitry Osipenko 
61424b94625SPaolo Bonzini     g_test_add_data_func(
6155b262bb6SDmitry Osipenko         g_strdup_printf("/ptimer/on_the_fly_period_change policy=%s", policy_name),
6165b262bb6SDmitry Osipenko         ppolicy, check_on_the_fly_period_change);
6175b262bb6SDmitry Osipenko 
61824b94625SPaolo Bonzini     g_test_add_data_func(
6195b262bb6SDmitry Osipenko         g_strdup_printf("/ptimer/on_the_fly_freq_change policy=%s", policy_name),
6205b262bb6SDmitry Osipenko         ppolicy, check_on_the_fly_freq_change);
6215b262bb6SDmitry Osipenko 
62224b94625SPaolo Bonzini     g_test_add_data_func(
6235b262bb6SDmitry Osipenko         g_strdup_printf("/ptimer/run_with_period_0 policy=%s", policy_name),
6245b262bb6SDmitry Osipenko         ppolicy, check_run_with_period_0);
6255b262bb6SDmitry Osipenko 
62624b94625SPaolo Bonzini     g_test_add_data_func(
6275b262bb6SDmitry Osipenko         g_strdup_printf("/ptimer/run_with_delta_0 policy=%s", policy_name),
6285b262bb6SDmitry Osipenko         ppolicy, check_run_with_delta_0);
6295b262bb6SDmitry Osipenko 
63024b94625SPaolo Bonzini     g_test_add_data_func(
6315b262bb6SDmitry Osipenko         g_strdup_printf("/ptimer/periodic_with_load_0 policy=%s", policy_name),
6325b262bb6SDmitry Osipenko         ppolicy, check_periodic_with_load_0);
6335b262bb6SDmitry Osipenko 
63424b94625SPaolo Bonzini     g_test_add_data_func(
6355b262bb6SDmitry Osipenko         g_strdup_printf("/ptimer/oneshot_with_load_0 policy=%s", policy_name),
6365b262bb6SDmitry Osipenko         ppolicy, check_oneshot_with_load_0);
6375b262bb6SDmitry Osipenko }
6385b262bb6SDmitry Osipenko 
639293130aaSDmitry Osipenko static void add_all_ptimer_policies_comb_tests(void)
640293130aaSDmitry Osipenko {
641*2e74583bSDmitry Osipenko     int last_policy = PTIMER_POLICY_CONTINUOUS_TRIGGER;
642293130aaSDmitry Osipenko     int policy = PTIMER_POLICY_DEFAULT;
643293130aaSDmitry Osipenko 
644293130aaSDmitry Osipenko     for (; policy < (last_policy << 1); policy++) {
645293130aaSDmitry Osipenko         add_ptimer_tests(policy);
646293130aaSDmitry Osipenko     }
647293130aaSDmitry Osipenko }
648293130aaSDmitry Osipenko 
6495b262bb6SDmitry Osipenko int main(int argc, char **argv)
6505b262bb6SDmitry Osipenko {
6515b262bb6SDmitry Osipenko     int i;
6525b262bb6SDmitry Osipenko 
6535b262bb6SDmitry Osipenko     g_test_init(&argc, &argv, NULL);
6545b262bb6SDmitry Osipenko 
6555b262bb6SDmitry Osipenko     for (i = 0; i < QEMU_CLOCK_MAX; i++) {
6565b262bb6SDmitry Osipenko         main_loop_tlg.tl[i] = g_new0(QEMUTimerList, 1);
6575b262bb6SDmitry Osipenko     }
6585b262bb6SDmitry Osipenko 
659293130aaSDmitry Osipenko     add_all_ptimer_policies_comb_tests();
6605b262bb6SDmitry Osipenko 
6615b262bb6SDmitry Osipenko     qtest_allowed = true;
6625b262bb6SDmitry Osipenko 
6635b262bb6SDmitry Osipenko     return g_test_run();
6645b262bb6SDmitry Osipenko }
665