]> git.proxmox.com Git - mirror_qemu.git/blame - tests/ptimer-test.c
Use #include "..." for our own headers, <...> for others
[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);
072bdb07 76 ptimer_free(ptimer);
5b262bb6
DO
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);
072bdb07 96 ptimer_free(ptimer);
5b262bb6
DO
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);
057516fe 104 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
5b262bb6
DO
105
106 triggered = false;
107
108 ptimer_set_period(ptimer, 2000000);
109 ptimer_set_count(ptimer, 10);
110 ptimer_run(ptimer, 1);
111
33d44cdf 112 qemu_clock_step(2000000 * 2 + 1);
5b262bb6 113
057516fe 114 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
5b262bb6
DO
115 g_assert_false(triggered);
116
117 ptimer_stop(ptimer);
118
057516fe 119 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
5b262bb6
DO
120 g_assert_false(triggered);
121
122 qemu_clock_step(2000000 * 11);
123
057516fe 124 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
5b262bb6
DO
125 g_assert_false(triggered);
126
127 ptimer_run(ptimer, 1);
128
33d44cdf 129 qemu_clock_step(2000000 * 7 + 1);
5b262bb6 130
057516fe 131 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
5b262bb6 132
057516fe
DO
133 if (no_round_down) {
134 g_assert_false(triggered);
135 } else {
136 g_assert_true(triggered);
137
138 triggered = false;
139 }
5b262bb6
DO
140
141 qemu_clock_step(2000000);
142
143 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
057516fe
DO
144
145 if (no_round_down) {
146 g_assert_true(triggered);
147
148 triggered = false;
149 } else {
150 g_assert_false(triggered);
151 }
5b262bb6
DO
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
33d44cdf 160 qemu_clock_step(20000000 + 1);
5b262bb6
DO
161
162 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
163 g_assert_false(triggered);
164
165 ptimer_set_limit(ptimer, 9, 1);
166
33d44cdf 167 qemu_clock_step(20000000 + 1);
5b262bb6
DO
168
169 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 9);
170 g_assert_false(triggered);
171
172 ptimer_run(ptimer, 1);
173
33d44cdf 174 qemu_clock_step(2000000 + 1);
5b262bb6 175
057516fe 176 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
5b262bb6
DO
177 g_assert_false(triggered);
178
179 ptimer_set_count(ptimer, 20);
180
33d44cdf 181 qemu_clock_step(2000000 * 19 + 1);
5b262bb6 182
057516fe 183 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
5b262bb6
DO
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
33d44cdf 195 qemu_clock_step(2000000 * 12 + 1);
5b262bb6
DO
196
197 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
198 g_assert_false(triggered);
072bdb07 199 ptimer_free(ptimer);
5b262bb6
DO
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);
293130aa 207 bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
516deb42 208 bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
56700e1a 209 bool no_immediate_reload = (*policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD);
057516fe 210 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
5b262bb6
DO
211
212 triggered = false;
213
214 ptimer_set_period(ptimer, 2000000);
215 ptimer_set_limit(ptimer, 10, 1);
216 ptimer_run(ptimer, 0);
217
293130aa
DO
218 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
219 g_assert_false(triggered);
220
33d44cdf 221 qemu_clock_step(1);
5b262bb6 222
057516fe 223 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 10 : 9);
293130aa
DO
224 g_assert_false(triggered);
225
33d44cdf 226 qemu_clock_step(2000000 * 10 - 1);
293130aa
DO
227
228 g_assert_cmpuint(ptimer_get_count(ptimer), ==, wrap_policy ? 0 : 10);
229 g_assert_true(triggered);
230
33d44cdf 231 qemu_clock_step(1);
293130aa 232
057516fe
DO
233 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
234 wrap_policy ? 0 : (no_round_down ? 10 : 9));
5b262bb6
DO
235 g_assert_true(triggered);
236
237 triggered = false;
238
239 qemu_clock_step(2000000);
240
057516fe
DO
241 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
242 (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
5b262bb6
DO
243 g_assert_false(triggered);
244
245 ptimer_set_count(ptimer, 20);
246
293130aa
DO
247 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 20);
248 g_assert_false(triggered);
249
33d44cdf 250 qemu_clock_step(1);
293130aa 251
057516fe 252 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 20 : 19);
293130aa
DO
253 g_assert_false(triggered);
254
33d44cdf 255 qemu_clock_step(2000000 * 11 + 1);
5b262bb6 256
057516fe 257 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 9 : 8);
5b262bb6
DO
258 g_assert_false(triggered);
259
260 qemu_clock_step(2000000 * 10);
261
057516fe
DO
262 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
263 (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
293130aa
DO
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
33d44cdf 273 qemu_clock_step(1);
293130aa 274
057516fe 275 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 3 : 2);
293130aa
DO
276 g_assert_false(triggered);
277
278 qemu_clock_step(2000000 * 4);
279
057516fe
DO
280 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
281 (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
5b262bb6
DO
282 g_assert_true(triggered);
283
284 ptimer_stop(ptimer);
285 triggered = false;
286
287 qemu_clock_step(2000000);
288
057516fe
DO
289 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
290 (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
5b262bb6
DO
291 g_assert_false(triggered);
292
293 ptimer_set_count(ptimer, 3);
294 ptimer_run(ptimer, 0);
295
33d44cdf 296 qemu_clock_step(2000000 * 3 + 1);
5b262bb6 297
057516fe
DO
298 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
299 wrap_policy ? 0 : (no_round_down ? 10 : 9));
5b262bb6
DO
300 g_assert_true(triggered);
301
302 triggered = false;
303
304 qemu_clock_step(2000000);
305
057516fe
DO
306 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
307 (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
5b262bb6
DO
308 g_assert_false(triggered);
309
310 ptimer_set_count(ptimer, 0);
56700e1a
DO
311 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
312 no_immediate_reload ? 0 : 10);
516deb42
DO
313
314 if (no_immediate_trigger) {
315 g_assert_false(triggered);
316 } else {
317 g_assert_true(triggered);
318 }
5b262bb6
DO
319
320 triggered = false;
321
33d44cdf 322 qemu_clock_step(1);
5b262bb6 323
56700e1a
DO
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
057516fe 339 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 10 : 9);
293130aa
DO
340 g_assert_false(triggered);
341
342 qemu_clock_step(2000000 * 12);
343
057516fe
DO
344 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
345 (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
5b262bb6
DO
346 g_assert_true(triggered);
347
348 ptimer_stop(ptimer);
349
350 triggered = false;
351
293130aa 352 qemu_clock_step(2000000 * 10);
5b262bb6 353
057516fe
DO
354 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
355 (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
5b262bb6
DO
356 g_assert_false(triggered);
357
358 ptimer_run(ptimer, 0);
359 ptimer_set_period(ptimer, 0);
360
33d44cdf 361 qemu_clock_step(2000000 + 1);
5b262bb6 362
057516fe
DO
363 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
364 (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
5b262bb6 365 g_assert_false(triggered);
072bdb07 366 ptimer_free(ptimer);
5b262bb6
DO
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);
293130aa 374 bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
057516fe 375 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
5b262bb6
DO
376
377 triggered = false;
378
379 ptimer_set_period(ptimer, 2000000);
380 ptimer_set_limit(ptimer, 10, 1);
381 ptimer_run(ptimer, 1);
382
33d44cdf 383 qemu_clock_step(2000000 * 9 + 1);
5b262bb6 384
057516fe 385 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
293130aa
DO
386 g_assert_false(triggered);
387
5b262bb6
DO
388 ptimer_run(ptimer, 0);
389
057516fe 390 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
5b262bb6
DO
391 g_assert_false(triggered);
392
393 qemu_clock_step(2000000);
394
057516fe
DO
395 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
396 wrap_policy ? 0 : (no_round_down ? 10 : 9));
5b262bb6
DO
397 g_assert_true(triggered);
398
399 triggered = false;
400
401 qemu_clock_step(2000000 * 9);
402
403 ptimer_run(ptimer, 1);
404
057516fe
DO
405 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
406 (no_round_down ? 1 : 0) + (wrap_policy ? 1 : 0));
5b262bb6
DO
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);
072bdb07 413 ptimer_free(ptimer);
5b262bb6
DO
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);
057516fe 421 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
5b262bb6
DO
422
423 triggered = false;
424
425 ptimer_set_period(ptimer, 2000000);
426 ptimer_set_limit(ptimer, 8, 1);
427 ptimer_run(ptimer, 1);
428
33d44cdf 429 qemu_clock_step(2000000 * 4 + 1);
5b262bb6 430
057516fe 431 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
5b262bb6
DO
432 g_assert_false(triggered);
433
434 ptimer_set_period(ptimer, 4000000);
057516fe 435 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
5b262bb6 436
33d44cdf 437 qemu_clock_step(4000000 * 2 + 1);
5b262bb6 438
057516fe 439 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 2 : 0);
5b262bb6
DO
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);
072bdb07 446 ptimer_free(ptimer);
5b262bb6
DO
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);
057516fe 454 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
5b262bb6
DO
455
456 triggered = false;
457
458 ptimer_set_freq(ptimer, 500);
459 ptimer_set_limit(ptimer, 8, 1);
460 ptimer_run(ptimer, 1);
461
33d44cdf 462 qemu_clock_step(2000000 * 4 + 1);
5b262bb6 463
057516fe 464 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
5b262bb6
DO
465 g_assert_false(triggered);
466
467 ptimer_set_freq(ptimer, 250);
057516fe 468 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
5b262bb6 469
33d44cdf 470 qemu_clock_step(2000000 * 4 + 1);
5b262bb6 471
057516fe 472 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 2 : 0);
5b262bb6
DO
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);
072bdb07 479 ptimer_free(ptimer);
5b262bb6
DO
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);
072bdb07 497 ptimer_free(ptimer);
5b262bb6
DO
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);
293130aa 505 bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
516deb42 506 bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
56700e1a 507 bool no_immediate_reload = (*policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD);
057516fe 508 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
5b262bb6
DO
509
510 triggered = false;
511
512 ptimer_set_period(ptimer, 2000000);
513 ptimer_set_limit(ptimer, 99, 0);
514 ptimer_run(ptimer, 1);
56700e1a
DO
515 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
516 no_immediate_reload ? 0 : 99);
516deb42
DO
517
518 if (no_immediate_trigger) {
519 g_assert_false(triggered);
520 } else {
521 g_assert_true(triggered);
522 }
5b262bb6
DO
523
524 triggered = false;
525
56700e1a 526 if (no_immediate_trigger || no_immediate_reload) {
33d44cdf 527 qemu_clock_step(2000000 + 1);
516deb42 528
56700e1a 529 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
057516fe 530 no_immediate_reload ? 0 : (no_round_down ? 98 : 97));
56700e1a
DO
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 }
516deb42
DO
539
540 ptimer_set_count(ptimer, 99);
541 ptimer_run(ptimer, 1);
542 }
543
33d44cdf 544 qemu_clock_step(2000000 + 1);
5b262bb6 545
057516fe 546 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 98 : 97);
5b262bb6
DO
547 g_assert_false(triggered);
548
549 qemu_clock_step(2000000 * 97);
550
057516fe 551 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
5b262bb6
DO
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);
56700e1a
DO
563 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
564 no_immediate_reload ? 0 : 99);
516deb42
DO
565
566 if (no_immediate_trigger) {
567 g_assert_false(triggered);
568 } else {
569 g_assert_true(triggered);
570 }
5b262bb6
DO
571
572 triggered = false;
573
33d44cdf 574 qemu_clock_step(1);
293130aa 575
56700e1a
DO
576 if (no_immediate_reload) {
577 qemu_clock_step(2000000);
578 }
579
057516fe 580 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 99 : 98);
56700e1a
DO
581
582 if (no_immediate_reload && no_immediate_trigger) {
583 g_assert_true(triggered);
584 } else {
585 g_assert_false(triggered);
586 }
293130aa
DO
587
588 triggered = false;
589
590 qemu_clock_step(2000000);
5b262bb6 591
057516fe 592 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 98 : 97);
5b262bb6
DO
593 g_assert_false(triggered);
594
595 qemu_clock_step(2000000 * 98);
596
057516fe
DO
597 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
598 wrap_policy ? 0 : (no_round_down ? 99 : 98));
5b262bb6
DO
599 g_assert_true(triggered);
600
601 ptimer_stop(ptimer);
072bdb07 602 ptimer_free(ptimer);
5b262bb6
DO
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);
2e74583b 610 bool continuous_trigger = (*policy & PTIMER_POLICY_CONTINUOUS_TRIGGER);
516deb42 611 bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
5b262bb6
DO
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);
516deb42
DO
619
620 if (no_immediate_trigger) {
621 g_assert_false(triggered);
622 } else {
623 g_assert_true(triggered);
624 }
5b262bb6
DO
625
626 triggered = false;
627
33d44cdf 628 qemu_clock_step(2000000 + 1);
5b262bb6
DO
629
630 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
2e74583b 631
516deb42 632 if (continuous_trigger || no_immediate_trigger) {
2e74583b
DO
633 g_assert_true(triggered);
634 } else {
635 g_assert_false(triggered);
636 }
5b262bb6 637
293130aa
DO
638 triggered = false;
639
640 ptimer_set_count(ptimer, 10);
641 ptimer_run(ptimer, 0);
642
33d44cdf 643 qemu_clock_step(2000000 * 10 + 1);
293130aa
DO
644
645 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
646 g_assert_true(triggered);
647
648 triggered = false;
649
33d44cdf 650 qemu_clock_step(2000000 + 1);
293130aa
DO
651
652 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
2e74583b
DO
653
654 if (continuous_trigger) {
655 g_assert_true(triggered);
656 } else {
657 g_assert_false(triggered);
658 }
293130aa 659
5b262bb6 660 ptimer_stop(ptimer);
072bdb07 661 ptimer_free(ptimer);
5b262bb6
DO
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);
516deb42 669 bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
5b262bb6
DO
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);
516deb42
DO
677
678 if (no_immediate_trigger) {
679 g_assert_false(triggered);
680 } else {
681 g_assert_true(triggered);
682 }
5b262bb6
DO
683
684 triggered = false;
685
33d44cdf 686 qemu_clock_step(2000000 + 1);
5b262bb6
DO
687
688 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
516deb42
DO
689
690 if (no_immediate_trigger) {
691 g_assert_true(triggered);
692 } else {
693 g_assert_false(triggered);
694 }
072bdb07
MAL
695
696 ptimer_free(ptimer);
5b262bb6
DO
697}
698
699static void add_ptimer_tests(uint8_t policy)
700{
072bdb07
MAL
701 char policy_name[256] = "";
702 char *tmp;
5b262bb6
DO
703
704 if (policy == PTIMER_POLICY_DEFAULT) {
705 g_sprintf(policy_name, "default");
706 }
707
293130aa
DO
708 if (policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD) {
709 g_strlcat(policy_name, "wrap_after_one_period,", 256);
710 }
711
2e74583b
DO
712 if (policy & PTIMER_POLICY_CONTINUOUS_TRIGGER) {
713 g_strlcat(policy_name, "continuous_trigger,", 256);
714 }
715
516deb42
DO
716 if (policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER) {
717 g_strlcat(policy_name, "no_immediate_trigger,", 256);
718 }
719
56700e1a
DO
720 if (policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD) {
721 g_strlcat(policy_name, "no_immediate_reload,", 256);
722 }
723
057516fe
DO
724 if (policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN) {
725 g_strlcat(policy_name, "no_counter_rounddown,", 256);
726 }
727
072bdb07
MAL
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);
5b262bb6
DO
789}
790
293130aa
DO
791static void add_all_ptimer_policies_comb_tests(void)
792{
057516fe 793 int last_policy = PTIMER_POLICY_NO_COUNTER_ROUND_DOWN;
293130aa
DO
794 int policy = PTIMER_POLICY_DEFAULT;
795
796 for (; policy < (last_policy << 1); policy++) {
797 add_ptimer_tests(policy);
798 }
799}
800
5b262bb6
DO
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
293130aa 811 add_all_ptimer_policies_comb_tests();
5b262bb6
DO
812
813 qtest_allowed = true;
814
815 return g_test_run();
816}