]> git.proxmox.com Git - mirror_qemu.git/blame - tests/ptimer-test.c
target/ppc: Eliminate htab_base and htab_mask variables
[mirror_qemu.git] / tests / ptimer-test.c
CommitLineData
5b262bb6
DO
1/*
2 * QTest testcase for the ptimer
3 *
673c7e89 4 * Copyright (c) 2016 Dmitry Osipenko <digetx@gmail.com>
5b262bb6
DO
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);
057516fe 102 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
5b262bb6
DO
103
104 triggered = false;
105
106 ptimer_set_period(ptimer, 2000000);
107 ptimer_set_count(ptimer, 10);
108 ptimer_run(ptimer, 1);
109
33d44cdf 110 qemu_clock_step(2000000 * 2 + 1);
5b262bb6 111
057516fe 112 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
5b262bb6
DO
113 g_assert_false(triggered);
114
115 ptimer_stop(ptimer);
116
057516fe 117 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
5b262bb6
DO
118 g_assert_false(triggered);
119
120 qemu_clock_step(2000000 * 11);
121
057516fe 122 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
5b262bb6
DO
123 g_assert_false(triggered);
124
125 ptimer_run(ptimer, 1);
126
33d44cdf 127 qemu_clock_step(2000000 * 7 + 1);
5b262bb6 128
057516fe 129 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
5b262bb6 130
057516fe
DO
131 if (no_round_down) {
132 g_assert_false(triggered);
133 } else {
134 g_assert_true(triggered);
135
136 triggered = false;
137 }
5b262bb6
DO
138
139 qemu_clock_step(2000000);
140
141 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
057516fe
DO
142
143 if (no_round_down) {
144 g_assert_true(triggered);
145
146 triggered = false;
147 } else {
148 g_assert_false(triggered);
149 }
5b262bb6
DO
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
33d44cdf 158 qemu_clock_step(20000000 + 1);
5b262bb6
DO
159
160 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
161 g_assert_false(triggered);
162
163 ptimer_set_limit(ptimer, 9, 1);
164
33d44cdf 165 qemu_clock_step(20000000 + 1);
5b262bb6
DO
166
167 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 9);
168 g_assert_false(triggered);
169
170 ptimer_run(ptimer, 1);
171
33d44cdf 172 qemu_clock_step(2000000 + 1);
5b262bb6 173
057516fe 174 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
5b262bb6
DO
175 g_assert_false(triggered);
176
177 ptimer_set_count(ptimer, 20);
178
33d44cdf 179 qemu_clock_step(2000000 * 19 + 1);
5b262bb6 180
057516fe 181 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
5b262bb6
DO
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
33d44cdf 193 qemu_clock_step(2000000 * 12 + 1);
5b262bb6
DO
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);
293130aa 204 bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
516deb42 205 bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
56700e1a 206 bool no_immediate_reload = (*policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD);
057516fe 207 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
5b262bb6
DO
208
209 triggered = false;
210
211 ptimer_set_period(ptimer, 2000000);
212 ptimer_set_limit(ptimer, 10, 1);
213 ptimer_run(ptimer, 0);
214
293130aa
DO
215 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
216 g_assert_false(triggered);
217
33d44cdf 218 qemu_clock_step(1);
5b262bb6 219
057516fe 220 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 10 : 9);
293130aa
DO
221 g_assert_false(triggered);
222
33d44cdf 223 qemu_clock_step(2000000 * 10 - 1);
293130aa
DO
224
225 g_assert_cmpuint(ptimer_get_count(ptimer), ==, wrap_policy ? 0 : 10);
226 g_assert_true(triggered);
227
33d44cdf 228 qemu_clock_step(1);
293130aa 229
057516fe
DO
230 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
231 wrap_policy ? 0 : (no_round_down ? 10 : 9));
5b262bb6
DO
232 g_assert_true(triggered);
233
234 triggered = false;
235
236 qemu_clock_step(2000000);
237
057516fe
DO
238 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
239 (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
5b262bb6
DO
240 g_assert_false(triggered);
241
242 ptimer_set_count(ptimer, 20);
243
293130aa
DO
244 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 20);
245 g_assert_false(triggered);
246
33d44cdf 247 qemu_clock_step(1);
293130aa 248
057516fe 249 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 20 : 19);
293130aa
DO
250 g_assert_false(triggered);
251
33d44cdf 252 qemu_clock_step(2000000 * 11 + 1);
5b262bb6 253
057516fe 254 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 9 : 8);
5b262bb6
DO
255 g_assert_false(triggered);
256
257 qemu_clock_step(2000000 * 10);
258
057516fe
DO
259 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
260 (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
293130aa
DO
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
33d44cdf 270 qemu_clock_step(1);
293130aa 271
057516fe 272 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 3 : 2);
293130aa
DO
273 g_assert_false(triggered);
274
275 qemu_clock_step(2000000 * 4);
276
057516fe
DO
277 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
278 (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
5b262bb6
DO
279 g_assert_true(triggered);
280
281 ptimer_stop(ptimer);
282 triggered = false;
283
284 qemu_clock_step(2000000);
285
057516fe
DO
286 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
287 (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
5b262bb6
DO
288 g_assert_false(triggered);
289
290 ptimer_set_count(ptimer, 3);
291 ptimer_run(ptimer, 0);
292
33d44cdf 293 qemu_clock_step(2000000 * 3 + 1);
5b262bb6 294
057516fe
DO
295 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
296 wrap_policy ? 0 : (no_round_down ? 10 : 9));
5b262bb6
DO
297 g_assert_true(triggered);
298
299 triggered = false;
300
301 qemu_clock_step(2000000);
302
057516fe
DO
303 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
304 (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
5b262bb6
DO
305 g_assert_false(triggered);
306
307 ptimer_set_count(ptimer, 0);
56700e1a
DO
308 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
309 no_immediate_reload ? 0 : 10);
516deb42
DO
310
311 if (no_immediate_trigger) {
312 g_assert_false(triggered);
313 } else {
314 g_assert_true(triggered);
315 }
5b262bb6
DO
316
317 triggered = false;
318
33d44cdf 319 qemu_clock_step(1);
5b262bb6 320
56700e1a
DO
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
057516fe 336 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 10 : 9);
293130aa
DO
337 g_assert_false(triggered);
338
339 qemu_clock_step(2000000 * 12);
340
057516fe
DO
341 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
342 (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
5b262bb6
DO
343 g_assert_true(triggered);
344
345 ptimer_stop(ptimer);
346
347 triggered = false;
348
293130aa 349 qemu_clock_step(2000000 * 10);
5b262bb6 350
057516fe
DO
351 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
352 (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
5b262bb6
DO
353 g_assert_false(triggered);
354
355 ptimer_run(ptimer, 0);
356 ptimer_set_period(ptimer, 0);
357
33d44cdf 358 qemu_clock_step(2000000 + 1);
5b262bb6 359
057516fe
DO
360 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
361 (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
5b262bb6
DO
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);
293130aa 370 bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
057516fe 371 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
5b262bb6
DO
372
373 triggered = false;
374
375 ptimer_set_period(ptimer, 2000000);
376 ptimer_set_limit(ptimer, 10, 1);
377 ptimer_run(ptimer, 1);
378
33d44cdf 379 qemu_clock_step(2000000 * 9 + 1);
5b262bb6 380
057516fe 381 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
293130aa
DO
382 g_assert_false(triggered);
383
5b262bb6
DO
384 ptimer_run(ptimer, 0);
385
057516fe 386 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
5b262bb6
DO
387 g_assert_false(triggered);
388
389 qemu_clock_step(2000000);
390
057516fe
DO
391 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
392 wrap_policy ? 0 : (no_round_down ? 10 : 9));
5b262bb6
DO
393 g_assert_true(triggered);
394
395 triggered = false;
396
397 qemu_clock_step(2000000 * 9);
398
399 ptimer_run(ptimer, 1);
400
057516fe
DO
401 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
402 (no_round_down ? 1 : 0) + (wrap_policy ? 1 : 0));
5b262bb6
DO
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);
057516fe 416 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
5b262bb6
DO
417
418 triggered = false;
419
420 ptimer_set_period(ptimer, 2000000);
421 ptimer_set_limit(ptimer, 8, 1);
422 ptimer_run(ptimer, 1);
423
33d44cdf 424 qemu_clock_step(2000000 * 4 + 1);
5b262bb6 425
057516fe 426 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
5b262bb6
DO
427 g_assert_false(triggered);
428
429 ptimer_set_period(ptimer, 4000000);
057516fe 430 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
5b262bb6 431
33d44cdf 432 qemu_clock_step(4000000 * 2 + 1);
5b262bb6 433
057516fe 434 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 2 : 0);
5b262bb6
DO
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);
057516fe 448 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
5b262bb6
DO
449
450 triggered = false;
451
452 ptimer_set_freq(ptimer, 500);
453 ptimer_set_limit(ptimer, 8, 1);
454 ptimer_run(ptimer, 1);
455
33d44cdf 456 qemu_clock_step(2000000 * 4 + 1);
5b262bb6 457
057516fe 458 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
5b262bb6
DO
459 g_assert_false(triggered);
460
461 ptimer_set_freq(ptimer, 250);
057516fe 462 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
5b262bb6 463
33d44cdf 464 qemu_clock_step(2000000 * 4 + 1);
5b262bb6 465
057516fe 466 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 2 : 0);
5b262bb6
DO
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);
293130aa 497 bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
516deb42 498 bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
56700e1a 499 bool no_immediate_reload = (*policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD);
057516fe 500 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
5b262bb6
DO
501
502 triggered = false;
503
504 ptimer_set_period(ptimer, 2000000);
505 ptimer_set_limit(ptimer, 99, 0);
506 ptimer_run(ptimer, 1);
56700e1a
DO
507 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
508 no_immediate_reload ? 0 : 99);
516deb42
DO
509
510 if (no_immediate_trigger) {
511 g_assert_false(triggered);
512 } else {
513 g_assert_true(triggered);
514 }
5b262bb6
DO
515
516 triggered = false;
517
56700e1a 518 if (no_immediate_trigger || no_immediate_reload) {
33d44cdf 519 qemu_clock_step(2000000 + 1);
516deb42 520
56700e1a 521 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
057516fe 522 no_immediate_reload ? 0 : (no_round_down ? 98 : 97));
56700e1a
DO
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 }
516deb42
DO
531
532 ptimer_set_count(ptimer, 99);
533 ptimer_run(ptimer, 1);
534 }
535
33d44cdf 536 qemu_clock_step(2000000 + 1);
5b262bb6 537
057516fe 538 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 98 : 97);
5b262bb6
DO
539 g_assert_false(triggered);
540
541 qemu_clock_step(2000000 * 97);
542
057516fe 543 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
5b262bb6
DO
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);
56700e1a
DO
555 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
556 no_immediate_reload ? 0 : 99);
516deb42
DO
557
558 if (no_immediate_trigger) {
559 g_assert_false(triggered);
560 } else {
561 g_assert_true(triggered);
562 }
5b262bb6
DO
563
564 triggered = false;
565
33d44cdf 566 qemu_clock_step(1);
293130aa 567
56700e1a
DO
568 if (no_immediate_reload) {
569 qemu_clock_step(2000000);
570 }
571
057516fe 572 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 99 : 98);
56700e1a
DO
573
574 if (no_immediate_reload && no_immediate_trigger) {
575 g_assert_true(triggered);
576 } else {
577 g_assert_false(triggered);
578 }
293130aa
DO
579
580 triggered = false;
581
582 qemu_clock_step(2000000);
5b262bb6 583
057516fe 584 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 98 : 97);
5b262bb6
DO
585 g_assert_false(triggered);
586
587 qemu_clock_step(2000000 * 98);
588
057516fe
DO
589 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
590 wrap_policy ? 0 : (no_round_down ? 99 : 98));
5b262bb6
DO
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);
2e74583b 601 bool continuous_trigger = (*policy & PTIMER_POLICY_CONTINUOUS_TRIGGER);
516deb42 602 bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
5b262bb6
DO
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);
516deb42
DO
610
611 if (no_immediate_trigger) {
612 g_assert_false(triggered);
613 } else {
614 g_assert_true(triggered);
615 }
5b262bb6
DO
616
617 triggered = false;
618
33d44cdf 619 qemu_clock_step(2000000 + 1);
5b262bb6
DO
620
621 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
2e74583b 622
516deb42 623 if (continuous_trigger || no_immediate_trigger) {
2e74583b
DO
624 g_assert_true(triggered);
625 } else {
626 g_assert_false(triggered);
627 }
5b262bb6 628
293130aa
DO
629 triggered = false;
630
631 ptimer_set_count(ptimer, 10);
632 ptimer_run(ptimer, 0);
633
33d44cdf 634 qemu_clock_step(2000000 * 10 + 1);
293130aa
DO
635
636 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
637 g_assert_true(triggered);
638
639 triggered = false;
640
33d44cdf 641 qemu_clock_step(2000000 + 1);
293130aa
DO
642
643 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
2e74583b
DO
644
645 if (continuous_trigger) {
646 g_assert_true(triggered);
647 } else {
648 g_assert_false(triggered);
649 }
293130aa 650
5b262bb6
DO
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);
516deb42 659 bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
5b262bb6
DO
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);
516deb42
DO
667
668 if (no_immediate_trigger) {
669 g_assert_false(triggered);
670 } else {
671 g_assert_true(triggered);
672 }
5b262bb6
DO
673
674 triggered = false;
675
33d44cdf 676 qemu_clock_step(2000000 + 1);
5b262bb6
DO
677
678 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
516deb42
DO
679
680 if (no_immediate_trigger) {
681 g_assert_true(triggered);
682 } else {
683 g_assert_false(triggered);
684 }
5b262bb6
DO
685}
686
687static void add_ptimer_tests(uint8_t policy)
688{
689 uint8_t *ppolicy = g_malloc(1);
293130aa 690 char *policy_name = g_malloc0(256);
5b262bb6
DO
691
692 *ppolicy = policy;
693
694 if (policy == PTIMER_POLICY_DEFAULT) {
695 g_sprintf(policy_name, "default");
696 }
697
293130aa
DO
698 if (policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD) {
699 g_strlcat(policy_name, "wrap_after_one_period,", 256);
700 }
701
2e74583b
DO
702 if (policy & PTIMER_POLICY_CONTINUOUS_TRIGGER) {
703 g_strlcat(policy_name, "continuous_trigger,", 256);
704 }
705
516deb42
DO
706 if (policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER) {
707 g_strlcat(policy_name, "no_immediate_trigger,", 256);
708 }
709
56700e1a
DO
710 if (policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD) {
711 g_strlcat(policy_name, "no_immediate_reload,", 256);
712 }
713
057516fe
DO
714 if (policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN) {
715 g_strlcat(policy_name, "no_counter_rounddown,", 256);
716 }
717
24b94625 718 g_test_add_data_func(
5b262bb6
DO
719 g_strdup_printf("/ptimer/set_count policy=%s", policy_name),
720 ppolicy, check_set_count);
721
24b94625 722 g_test_add_data_func(
5b262bb6
DO
723 g_strdup_printf("/ptimer/set_limit policy=%s", policy_name),
724 ppolicy, check_set_limit);
725
24b94625 726 g_test_add_data_func(
5b262bb6
DO
727 g_strdup_printf("/ptimer/oneshot policy=%s", policy_name),
728 ppolicy, check_oneshot);
729
24b94625 730 g_test_add_data_func(
5b262bb6
DO
731 g_strdup_printf("/ptimer/periodic policy=%s", policy_name),
732 ppolicy, check_periodic);
733
24b94625 734 g_test_add_data_func(
5b262bb6
DO
735 g_strdup_printf("/ptimer/on_the_fly_mode_change policy=%s", policy_name),
736 ppolicy, check_on_the_fly_mode_change);
737
24b94625 738 g_test_add_data_func(
5b262bb6
DO
739 g_strdup_printf("/ptimer/on_the_fly_period_change policy=%s", policy_name),
740 ppolicy, check_on_the_fly_period_change);
741
24b94625 742 g_test_add_data_func(
5b262bb6
DO
743 g_strdup_printf("/ptimer/on_the_fly_freq_change policy=%s", policy_name),
744 ppolicy, check_on_the_fly_freq_change);
745
24b94625 746 g_test_add_data_func(
5b262bb6
DO
747 g_strdup_printf("/ptimer/run_with_period_0 policy=%s", policy_name),
748 ppolicy, check_run_with_period_0);
749
24b94625 750 g_test_add_data_func(
5b262bb6
DO
751 g_strdup_printf("/ptimer/run_with_delta_0 policy=%s", policy_name),
752 ppolicy, check_run_with_delta_0);
753
24b94625 754 g_test_add_data_func(
5b262bb6
DO
755 g_strdup_printf("/ptimer/periodic_with_load_0 policy=%s", policy_name),
756 ppolicy, check_periodic_with_load_0);
757
24b94625 758 g_test_add_data_func(
5b262bb6
DO
759 g_strdup_printf("/ptimer/oneshot_with_load_0 policy=%s", policy_name),
760 ppolicy, check_oneshot_with_load_0);
761}
762
293130aa
DO
763static void add_all_ptimer_policies_comb_tests(void)
764{
057516fe 765 int last_policy = PTIMER_POLICY_NO_COUNTER_ROUND_DOWN;
293130aa
DO
766 int policy = PTIMER_POLICY_DEFAULT;
767
768 for (; policy < (last_policy << 1); policy++) {
769 add_ptimer_tests(policy);
770 }
771}
772
5b262bb6
DO
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
293130aa 783 add_all_ptimer_policies_comb_tests();
5b262bb6
DO
784
785 qtest_allowed = true;
786
787 return g_test_run();
788}