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