OSDN Git Service

block: Protect bs->backing with graph_lock
[qmiga/qemu.git] / tests / unit / ptimer-test.c
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 }