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