qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

ptimer-test.c (25207B)


      1 /*
      2  * QTest testcase for the ptimer
      3  *
      4  * Copyright (c) 2016 Dmitry Osipenko <digetx@gmail.com>
      5  *
      6  * This work is licensed under the terms of the GNU GPL, version 2 or later.
      7  * See the COPYING file in the top-level directory.
      8  *
      9  */
     10 
     11 #include "qemu/osdep.h"
     12 #include <glib/gprintf.h>
     13 
     14 #include "qemu/main-loop.h"
     15 #include "hw/ptimer.h"
     16 
     17 #include "ptimer-test.h"
     18 
     19 static bool triggered;
     20 
     21 static void ptimer_trigger(void *opaque)
     22 {
     23     triggered = true;
     24 }
     25 
     26 static void ptimer_test_expire_qemu_timers(int64_t expire_time,
     27                                            QEMUClockType type)
     28 {
     29     QEMUTimerList *timer_list = main_loop_tlg.tl[type];
     30     QEMUTimer *t = timer_list->active_timers.next;
     31 
     32     while (t != NULL) {
     33         if (t->expire_time == expire_time) {
     34             timer_del(t);
     35 
     36             if (t->cb != NULL) {
     37                 t->cb(t->opaque);
     38             }
     39         }
     40 
     41         t = t->next;
     42     }
     43 }
     44 
     45 static void ptimer_test_set_qemu_time_ns(int64_t ns)
     46 {
     47     ptimer_test_time_ns = ns;
     48 }
     49 
     50 static void qemu_clock_step(uint64_t ns)
     51 {
     52     int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
     53                                                   QEMU_TIMER_ATTR_ALL);
     54     int64_t advanced_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns;
     55 
     56     while (deadline != -1 && deadline <= advanced_time) {
     57         ptimer_test_set_qemu_time_ns(deadline);
     58         ptimer_test_expire_qemu_timers(deadline, QEMU_CLOCK_VIRTUAL);
     59         deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
     60                                               QEMU_TIMER_ATTR_ALL);
     61     }
     62 
     63     ptimer_test_set_qemu_time_ns(advanced_time);
     64 }
     65 
     66 static void check_set_count(gconstpointer arg)
     67 {
     68     const uint8_t *policy = arg;
     69     ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
     70 
     71     triggered = false;
     72 
     73     ptimer_transaction_begin(ptimer);
     74     ptimer_set_count(ptimer, 1000);
     75     ptimer_transaction_commit(ptimer);
     76     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 1000);
     77     g_assert_false(triggered);
     78     ptimer_free(ptimer);
     79 }
     80 
     81 static void check_set_limit(gconstpointer arg)
     82 {
     83     const uint8_t *policy = arg;
     84     ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
     85 
     86     triggered = false;
     87 
     88     ptimer_transaction_begin(ptimer);
     89     ptimer_set_limit(ptimer, 1000, 0);
     90     ptimer_transaction_commit(ptimer);
     91     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
     92     g_assert_cmpuint(ptimer_get_limit(ptimer), ==, 1000);
     93     g_assert_false(triggered);
     94 
     95     ptimer_transaction_begin(ptimer);
     96     ptimer_set_limit(ptimer, 2000, 1);
     97     ptimer_transaction_commit(ptimer);
     98     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 2000);
     99     g_assert_cmpuint(ptimer_get_limit(ptimer), ==, 2000);
    100     g_assert_false(triggered);
    101     ptimer_free(ptimer);
    102 }
    103 
    104 static void check_oneshot(gconstpointer arg)
    105 {
    106     const uint8_t *policy = arg;
    107     ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
    108     bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
    109 
    110     triggered = false;
    111 
    112     ptimer_transaction_begin(ptimer);
    113     ptimer_set_period(ptimer, 2000000);
    114     ptimer_set_count(ptimer, 10);
    115     ptimer_run(ptimer, 1);
    116     ptimer_transaction_commit(ptimer);
    117 
    118     qemu_clock_step(2000000 * 2 + 1);
    119 
    120     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
    121     g_assert_false(triggered);
    122 
    123     ptimer_transaction_begin(ptimer);
    124     ptimer_stop(ptimer);
    125     ptimer_transaction_commit(ptimer);
    126 
    127     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
    128     g_assert_false(triggered);
    129 
    130     qemu_clock_step(2000000 * 11);
    131 
    132     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
    133     g_assert_false(triggered);
    134 
    135     ptimer_transaction_begin(ptimer);
    136     ptimer_run(ptimer, 1);
    137     ptimer_transaction_commit(ptimer);
    138 
    139     qemu_clock_step(2000000 * 7 + 1);
    140 
    141     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
    142 
    143     if (no_round_down) {
    144         g_assert_false(triggered);
    145     } else {
    146         g_assert_true(triggered);
    147 
    148         triggered = false;
    149     }
    150 
    151     qemu_clock_step(2000000);
    152 
    153     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    154 
    155     if (no_round_down) {
    156         g_assert_true(triggered);
    157 
    158         triggered = false;
    159     } else {
    160         g_assert_false(triggered);
    161     }
    162 
    163     qemu_clock_step(4000000);
    164 
    165     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    166     g_assert_false(triggered);
    167 
    168     ptimer_transaction_begin(ptimer);
    169     ptimer_set_count(ptimer, 10);
    170     ptimer_transaction_commit(ptimer);
    171 
    172     qemu_clock_step(20000000 + 1);
    173 
    174     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
    175     g_assert_false(triggered);
    176 
    177     ptimer_transaction_begin(ptimer);
    178     ptimer_set_limit(ptimer, 9, 1);
    179     ptimer_transaction_commit(ptimer);
    180 
    181     qemu_clock_step(20000000 + 1);
    182 
    183     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 9);
    184     g_assert_false(triggered);
    185 
    186     ptimer_transaction_begin(ptimer);
    187     ptimer_run(ptimer, 1);
    188     ptimer_transaction_commit(ptimer);
    189 
    190     qemu_clock_step(2000000 + 1);
    191 
    192     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
    193     g_assert_false(triggered);
    194 
    195     ptimer_transaction_begin(ptimer);
    196     ptimer_set_count(ptimer, 20);
    197     ptimer_transaction_commit(ptimer);
    198 
    199     qemu_clock_step(2000000 * 19 + 1);
    200 
    201     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
    202     g_assert_false(triggered);
    203 
    204     qemu_clock_step(2000000);
    205 
    206     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    207     g_assert_true(triggered);
    208 
    209     ptimer_transaction_begin(ptimer);
    210     ptimer_stop(ptimer);
    211     ptimer_transaction_commit(ptimer);
    212 
    213     triggered = false;
    214 
    215     qemu_clock_step(2000000 * 12 + 1);
    216 
    217     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    218     g_assert_false(triggered);
    219     ptimer_free(ptimer);
    220 }
    221 
    222 static void check_periodic(gconstpointer arg)
    223 {
    224     const uint8_t *policy = arg;
    225     ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
    226     bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
    227     bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
    228     bool no_immediate_reload = (*policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD);
    229     bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
    230     bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
    231 
    232     triggered = false;
    233 
    234     ptimer_transaction_begin(ptimer);
    235     ptimer_set_period(ptimer, 2000000);
    236     ptimer_set_limit(ptimer, 10, 1);
    237     ptimer_run(ptimer, 0);
    238     ptimer_transaction_commit(ptimer);
    239 
    240     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
    241     g_assert_false(triggered);
    242 
    243     qemu_clock_step(1);
    244 
    245     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 10 : 9);
    246     g_assert_false(triggered);
    247 
    248     qemu_clock_step(2000000 * 10 - 1);
    249 
    250     g_assert_cmpuint(ptimer_get_count(ptimer), ==, wrap_policy ? 0 : 10);
    251     g_assert_true(triggered);
    252 
    253     qemu_clock_step(1);
    254 
    255     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    256                      wrap_policy ? 0 : (no_round_down ? 10 : 9));
    257     g_assert_true(triggered);
    258 
    259     triggered = false;
    260 
    261     qemu_clock_step(2000000);
    262 
    263     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    264                     (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
    265     g_assert_false(triggered);
    266 
    267     ptimer_transaction_begin(ptimer);
    268     ptimer_set_count(ptimer, 20);
    269     ptimer_transaction_commit(ptimer);
    270 
    271     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 20);
    272     g_assert_false(triggered);
    273 
    274     qemu_clock_step(1);
    275 
    276     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 20 : 19);
    277     g_assert_false(triggered);
    278 
    279     qemu_clock_step(2000000 * 11 + 1);
    280 
    281     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 9 : 8);
    282     g_assert_false(triggered);
    283 
    284     qemu_clock_step(2000000 * 10);
    285 
    286     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    287                     (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
    288     g_assert_true(triggered);
    289 
    290     triggered = false;
    291 
    292     ptimer_transaction_begin(ptimer);
    293     ptimer_set_count(ptimer, 3);
    294     ptimer_transaction_commit(ptimer);
    295 
    296     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 3);
    297     g_assert_false(triggered);
    298 
    299     qemu_clock_step(1);
    300 
    301     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 3 : 2);
    302     g_assert_false(triggered);
    303 
    304     qemu_clock_step(2000000 * 4);
    305 
    306     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    307                     (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
    308     g_assert_true(triggered);
    309 
    310     ptimer_transaction_begin(ptimer);
    311     ptimer_stop(ptimer);
    312     ptimer_transaction_commit(ptimer);
    313     triggered = false;
    314 
    315     qemu_clock_step(2000000);
    316 
    317     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    318                     (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
    319     g_assert_false(triggered);
    320 
    321     ptimer_transaction_begin(ptimer);
    322     ptimer_set_count(ptimer, 3);
    323     ptimer_run(ptimer, 0);
    324     ptimer_transaction_commit(ptimer);
    325 
    326     qemu_clock_step(2000000 * 3 + 1);
    327 
    328     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    329                      wrap_policy ? 0 : (no_round_down ? 10 : 9));
    330     g_assert_true(triggered);
    331 
    332     triggered = false;
    333 
    334     qemu_clock_step(2000000);
    335 
    336     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    337                     (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
    338     g_assert_false(triggered);
    339 
    340     ptimer_transaction_begin(ptimer);
    341     ptimer_set_count(ptimer, 0);
    342     ptimer_transaction_commit(ptimer);
    343     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    344                      no_immediate_reload ? 0 : 10);
    345 
    346     if (no_immediate_trigger || trig_only_on_dec) {
    347         g_assert_false(triggered);
    348     } else {
    349         g_assert_true(triggered);
    350     }
    351 
    352     triggered = false;
    353 
    354     qemu_clock_step(1);
    355 
    356     if (no_immediate_reload) {
    357         g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    358         g_assert_false(triggered);
    359 
    360         qemu_clock_step(2000000);
    361 
    362         if (no_immediate_trigger) {
    363             g_assert_true(triggered);
    364         } else {
    365             g_assert_false(triggered);
    366         }
    367 
    368         triggered = false;
    369     }
    370 
    371     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 10 : 9);
    372     g_assert_false(triggered);
    373 
    374     qemu_clock_step(2000000 * 12);
    375 
    376     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    377                     (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
    378     g_assert_true(triggered);
    379 
    380     ptimer_transaction_begin(ptimer);
    381     ptimer_stop(ptimer);
    382     ptimer_transaction_commit(ptimer);
    383 
    384     triggered = false;
    385 
    386     qemu_clock_step(2000000 * 10);
    387 
    388     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    389                     (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
    390     g_assert_false(triggered);
    391 
    392     ptimer_transaction_begin(ptimer);
    393     ptimer_run(ptimer, 0);
    394     ptimer_transaction_commit(ptimer);
    395 
    396     ptimer_transaction_begin(ptimer);
    397     ptimer_set_period(ptimer, 0);
    398     ptimer_transaction_commit(ptimer);
    399 
    400     qemu_clock_step(2000000 + 1);
    401 
    402     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    403                     (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
    404     g_assert_false(triggered);
    405     ptimer_free(ptimer);
    406 }
    407 
    408 static void check_on_the_fly_mode_change(gconstpointer arg)
    409 {
    410     const uint8_t *policy = arg;
    411     ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
    412     bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
    413     bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
    414 
    415     triggered = false;
    416 
    417     ptimer_transaction_begin(ptimer);
    418     ptimer_set_period(ptimer, 2000000);
    419     ptimer_set_limit(ptimer, 10, 1);
    420     ptimer_run(ptimer, 1);
    421     ptimer_transaction_commit(ptimer);
    422 
    423     qemu_clock_step(2000000 * 9 + 1);
    424 
    425     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
    426     g_assert_false(triggered);
    427 
    428     ptimer_transaction_begin(ptimer);
    429     ptimer_run(ptimer, 0);
    430     ptimer_transaction_commit(ptimer);
    431 
    432     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
    433     g_assert_false(triggered);
    434 
    435     qemu_clock_step(2000000);
    436 
    437     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    438                     wrap_policy ? 0 : (no_round_down ? 10 : 9));
    439     g_assert_true(triggered);
    440 
    441     triggered = false;
    442 
    443     qemu_clock_step(2000000 * 9);
    444 
    445     ptimer_transaction_begin(ptimer);
    446     ptimer_run(ptimer, 1);
    447     ptimer_transaction_commit(ptimer);
    448 
    449     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    450                      (no_round_down ? 1 : 0) + (wrap_policy ? 1 : 0));
    451     g_assert_false(triggered);
    452 
    453     qemu_clock_step(2000000 * 3);
    454 
    455     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    456     g_assert_true(triggered);
    457     ptimer_free(ptimer);
    458 }
    459 
    460 static void check_on_the_fly_period_change(gconstpointer arg)
    461 {
    462     const uint8_t *policy = arg;
    463     ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
    464     bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
    465 
    466     triggered = false;
    467 
    468     ptimer_transaction_begin(ptimer);
    469     ptimer_set_period(ptimer, 2000000);
    470     ptimer_set_limit(ptimer, 8, 1);
    471     ptimer_run(ptimer, 1);
    472     ptimer_transaction_commit(ptimer);
    473 
    474     qemu_clock_step(2000000 * 4 + 1);
    475 
    476     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
    477     g_assert_false(triggered);
    478 
    479     ptimer_transaction_begin(ptimer);
    480     ptimer_set_period(ptimer, 4000000);
    481     ptimer_transaction_commit(ptimer);
    482     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
    483 
    484     qemu_clock_step(4000000 * 2 + 1);
    485 
    486     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 2 : 0);
    487     g_assert_false(triggered);
    488 
    489     qemu_clock_step(4000000 * 2);
    490 
    491     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    492     g_assert_true(triggered);
    493     ptimer_free(ptimer);
    494 }
    495 
    496 static void check_on_the_fly_freq_change(gconstpointer arg)
    497 {
    498     const uint8_t *policy = arg;
    499     ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
    500     bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
    501 
    502     triggered = false;
    503 
    504     ptimer_transaction_begin(ptimer);
    505     ptimer_set_freq(ptimer, 500);
    506     ptimer_set_limit(ptimer, 8, 1);
    507     ptimer_run(ptimer, 1);
    508     ptimer_transaction_commit(ptimer);
    509 
    510     qemu_clock_step(2000000 * 4 + 1);
    511 
    512     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
    513     g_assert_false(triggered);
    514 
    515     ptimer_transaction_begin(ptimer);
    516     ptimer_set_freq(ptimer, 250);
    517     ptimer_transaction_commit(ptimer);
    518     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
    519 
    520     qemu_clock_step(2000000 * 4 + 1);
    521 
    522     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 2 : 0);
    523     g_assert_false(triggered);
    524 
    525     qemu_clock_step(2000000 * 4);
    526 
    527     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    528     g_assert_true(triggered);
    529     ptimer_free(ptimer);
    530 }
    531 
    532 static void check_run_with_period_0(gconstpointer arg)
    533 {
    534     const uint8_t *policy = arg;
    535     ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
    536 
    537     triggered = false;
    538 
    539     ptimer_transaction_begin(ptimer);
    540     ptimer_set_count(ptimer, 99);
    541     ptimer_run(ptimer, 1);
    542     ptimer_transaction_commit(ptimer);
    543 
    544     qemu_clock_step(10 * NANOSECONDS_PER_SECOND);
    545 
    546     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 99);
    547     g_assert_false(triggered);
    548     ptimer_free(ptimer);
    549 }
    550 
    551 static void check_run_with_delta_0(gconstpointer arg)
    552 {
    553     const uint8_t *policy = arg;
    554     ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
    555     bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
    556     bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
    557     bool no_immediate_reload = (*policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD);
    558     bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
    559     bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
    560 
    561     triggered = false;
    562 
    563     ptimer_transaction_begin(ptimer);
    564     ptimer_set_period(ptimer, 2000000);
    565     ptimer_set_limit(ptimer, 99, 0);
    566     ptimer_run(ptimer, 1);
    567     ptimer_transaction_commit(ptimer);
    568     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    569                      no_immediate_reload ? 0 : 99);
    570 
    571     if (no_immediate_trigger || trig_only_on_dec) {
    572         g_assert_false(triggered);
    573     } else {
    574         g_assert_true(triggered);
    575     }
    576 
    577     triggered = false;
    578 
    579     if (no_immediate_trigger || no_immediate_reload) {
    580         qemu_clock_step(2000000 + 1);
    581 
    582         g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    583                          no_immediate_reload ? 0 : (no_round_down ? 98 : 97));
    584 
    585         if (no_immediate_trigger && no_immediate_reload) {
    586             g_assert_true(triggered);
    587 
    588             triggered = false;
    589         } else {
    590             g_assert_false(triggered);
    591         }
    592 
    593         ptimer_transaction_begin(ptimer);
    594         ptimer_set_count(ptimer, 99);
    595         ptimer_run(ptimer, 1);
    596         ptimer_transaction_commit(ptimer);
    597     }
    598 
    599     qemu_clock_step(2000000 + 1);
    600 
    601     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 98 : 97);
    602     g_assert_false(triggered);
    603 
    604     qemu_clock_step(2000000 * 97);
    605 
    606     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
    607     g_assert_false(triggered);
    608 
    609     qemu_clock_step(2000000 * 2);
    610 
    611     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    612     g_assert_true(triggered);
    613 
    614     triggered = false;
    615 
    616     ptimer_transaction_begin(ptimer);
    617     ptimer_set_count(ptimer, 0);
    618     ptimer_run(ptimer, 0);
    619     ptimer_transaction_commit(ptimer);
    620     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    621                      no_immediate_reload ? 0 : 99);
    622 
    623     if (no_immediate_trigger || trig_only_on_dec) {
    624         g_assert_false(triggered);
    625     } else {
    626         g_assert_true(triggered);
    627     }
    628 
    629     triggered = false;
    630 
    631     qemu_clock_step(1);
    632 
    633     if (no_immediate_reload) {
    634         qemu_clock_step(2000000);
    635     }
    636 
    637     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 99 : 98);
    638 
    639     if (no_immediate_reload && no_immediate_trigger) {
    640         g_assert_true(triggered);
    641     } else {
    642         g_assert_false(triggered);
    643     }
    644 
    645     triggered = false;
    646 
    647     qemu_clock_step(2000000);
    648 
    649     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 98 : 97);
    650     g_assert_false(triggered);
    651 
    652     qemu_clock_step(2000000 * 98);
    653 
    654     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    655                     wrap_policy ? 0 : (no_round_down ? 99 : 98));
    656     g_assert_true(triggered);
    657 
    658     ptimer_transaction_begin(ptimer);
    659     ptimer_stop(ptimer);
    660     ptimer_transaction_commit(ptimer);
    661     ptimer_free(ptimer);
    662 }
    663 
    664 static void check_periodic_with_load_0(gconstpointer arg)
    665 {
    666     const uint8_t *policy = arg;
    667     ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
    668     bool continuous_trigger = (*policy & PTIMER_POLICY_CONTINUOUS_TRIGGER);
    669     bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
    670     bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
    671 
    672     triggered = false;
    673 
    674     ptimer_transaction_begin(ptimer);
    675     ptimer_set_period(ptimer, 2000000);
    676     ptimer_run(ptimer, 0);
    677     ptimer_transaction_commit(ptimer);
    678 
    679     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    680 
    681     if (no_immediate_trigger || trig_only_on_dec) {
    682         g_assert_false(triggered);
    683     } else {
    684         g_assert_true(triggered);
    685     }
    686 
    687     triggered = false;
    688 
    689     qemu_clock_step(2000000 + 1);
    690 
    691     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    692 
    693     if (continuous_trigger || no_immediate_trigger) {
    694         g_assert_true(triggered);
    695     } else {
    696         g_assert_false(triggered);
    697     }
    698 
    699     triggered = false;
    700 
    701     ptimer_transaction_begin(ptimer);
    702     ptimer_set_count(ptimer, 10);
    703     ptimer_run(ptimer, 0);
    704     ptimer_transaction_commit(ptimer);
    705 
    706     qemu_clock_step(2000000 * 10 + 1);
    707 
    708     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    709     g_assert_true(triggered);
    710 
    711     triggered = false;
    712 
    713     qemu_clock_step(2000000 + 1);
    714 
    715     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    716 
    717     if (continuous_trigger) {
    718         g_assert_true(triggered);
    719     } else {
    720         g_assert_false(triggered);
    721     }
    722 
    723     ptimer_transaction_begin(ptimer);
    724     ptimer_stop(ptimer);
    725     ptimer_transaction_commit(ptimer);
    726     ptimer_free(ptimer);
    727 }
    728 
    729 static void check_oneshot_with_load_0(gconstpointer arg)
    730 {
    731     const uint8_t *policy = arg;
    732     ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
    733     bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
    734     bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
    735 
    736     triggered = false;
    737 
    738     ptimer_transaction_begin(ptimer);
    739     ptimer_set_period(ptimer, 2000000);
    740     ptimer_run(ptimer, 1);
    741     ptimer_transaction_commit(ptimer);
    742 
    743     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    744 
    745     if (no_immediate_trigger || trig_only_on_dec) {
    746         g_assert_false(triggered);
    747     } else {
    748         g_assert_true(triggered);
    749     }
    750 
    751     triggered = false;
    752 
    753     qemu_clock_step(2000000 + 1);
    754 
    755     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    756 
    757     if (no_immediate_trigger) {
    758         g_assert_true(triggered);
    759     } else {
    760         g_assert_false(triggered);
    761     }
    762 
    763     ptimer_free(ptimer);
    764 }
    765 
    766 static void add_ptimer_tests(uint8_t policy)
    767 {
    768     char policy_name[256] = "";
    769     char *tmp;
    770 
    771     if (policy == PTIMER_POLICY_LEGACY) {
    772         g_sprintf(policy_name, "legacy");
    773     }
    774 
    775     if (policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD) {
    776         g_strlcat(policy_name, "wrap_after_one_period,", 256);
    777     }
    778 
    779     if (policy & PTIMER_POLICY_CONTINUOUS_TRIGGER) {
    780         g_strlcat(policy_name, "continuous_trigger,", 256);
    781     }
    782 
    783     if (policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER) {
    784         g_strlcat(policy_name, "no_immediate_trigger,", 256);
    785     }
    786 
    787     if (policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD) {
    788         g_strlcat(policy_name, "no_immediate_reload,", 256);
    789     }
    790 
    791     if (policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN) {
    792         g_strlcat(policy_name, "no_counter_rounddown,", 256);
    793     }
    794 
    795     if (policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) {
    796         g_strlcat(policy_name, "trigger_only_on_decrement,", 256);
    797     }
    798 
    799     g_test_add_data_func_full(
    800         tmp = g_strdup_printf("/ptimer/set_count policy=%s", policy_name),
    801         g_memdup2(&policy, 1), check_set_count, g_free);
    802     g_free(tmp);
    803 
    804     g_test_add_data_func_full(
    805         tmp = g_strdup_printf("/ptimer/set_limit policy=%s", policy_name),
    806         g_memdup2(&policy, 1), check_set_limit, g_free);
    807     g_free(tmp);
    808 
    809     g_test_add_data_func_full(
    810         tmp = g_strdup_printf("/ptimer/oneshot policy=%s", policy_name),
    811         g_memdup2(&policy, 1), check_oneshot, g_free);
    812     g_free(tmp);
    813 
    814     g_test_add_data_func_full(
    815         tmp = g_strdup_printf("/ptimer/periodic policy=%s", policy_name),
    816         g_memdup2(&policy, 1), check_periodic, g_free);
    817     g_free(tmp);
    818 
    819     g_test_add_data_func_full(
    820         tmp = g_strdup_printf("/ptimer/on_the_fly_mode_change policy=%s",
    821                               policy_name),
    822         g_memdup2(&policy, 1), check_on_the_fly_mode_change, g_free);
    823     g_free(tmp);
    824 
    825     g_test_add_data_func_full(
    826         tmp = g_strdup_printf("/ptimer/on_the_fly_period_change policy=%s",
    827                               policy_name),
    828         g_memdup2(&policy, 1), check_on_the_fly_period_change, g_free);
    829     g_free(tmp);
    830 
    831     g_test_add_data_func_full(
    832         tmp = g_strdup_printf("/ptimer/on_the_fly_freq_change policy=%s",
    833                               policy_name),
    834         g_memdup2(&policy, 1), check_on_the_fly_freq_change, g_free);
    835     g_free(tmp);
    836 
    837     g_test_add_data_func_full(
    838         tmp = g_strdup_printf("/ptimer/run_with_period_0 policy=%s",
    839                               policy_name),
    840         g_memdup2(&policy, 1), check_run_with_period_0, g_free);
    841     g_free(tmp);
    842 
    843     g_test_add_data_func_full(
    844         tmp = g_strdup_printf("/ptimer/run_with_delta_0 policy=%s",
    845                               policy_name),
    846         g_memdup2(&policy, 1), check_run_with_delta_0, g_free);
    847     g_free(tmp);
    848 
    849     g_test_add_data_func_full(
    850         tmp = g_strdup_printf("/ptimer/periodic_with_load_0 policy=%s",
    851                               policy_name),
    852         g_memdup2(&policy, 1), check_periodic_with_load_0, g_free);
    853     g_free(tmp);
    854 
    855     g_test_add_data_func_full(
    856         tmp = g_strdup_printf("/ptimer/oneshot_with_load_0 policy=%s",
    857                               policy_name),
    858         g_memdup2(&policy, 1), check_oneshot_with_load_0, g_free);
    859     g_free(tmp);
    860 }
    861 
    862 static void add_all_ptimer_policies_comb_tests(void)
    863 {
    864     int last_policy = PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT;
    865     int policy = PTIMER_POLICY_LEGACY;
    866 
    867     for (; policy < (last_policy << 1); policy++) {
    868         if ((policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) &&
    869             (policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER)) {
    870             /* Incompatible policy flag settings -- don't try to test them */
    871             continue;
    872         }
    873         add_ptimer_tests(policy);
    874     }
    875 }
    876 
    877 int main(int argc, char **argv)
    878 {
    879     int i;
    880 
    881     g_test_init(&argc, &argv, NULL);
    882 
    883     for (i = 0; i < QEMU_CLOCK_MAX; i++) {
    884         main_loop_tlg.tl[i] = g_new0(QEMUTimerList, 1);
    885     }
    886 
    887     add_all_ptimer_policies_comb_tests();
    888 
    889     qtest_allowed = true;
    890 
    891     return g_test_run();
    892 }