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 } 893