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