]> git.proxmox.com Git - mirror_qemu.git/blame - tests/ptimer-test.c
migration/postcopy: enable compress during postcopy
[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
8f0a3716 11#include "qemu/osdep.h"
5b262bb6
DO
12#include <glib/gprintf.h>
13
5b262bb6
DO
14#include "qemu/main-loop.h"
15#include "hw/ptimer.h"
16
5b262bb6
DO
17#include "ptimer-test.h"
18
19static bool triggered;
20
21static void ptimer_trigger(void *opaque)
22{
23 triggered = true;
24}
25
26static 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
45static void ptimer_test_set_qemu_time_ns(int64_t ns)
46{
47 ptimer_test_time_ns = ns;
48}
49
50static void qemu_clock_step(uint64_t ns)
51{
dcb15780
PD
52 int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
53 QEMU_TIMER_ATTR_ALL);
5b262bb6
DO
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);
dcb15780
PD
59 deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
60 QEMU_TIMER_ATTR_ALL);
5b262bb6
DO
61 }
62
63 ptimer_test_set_qemu_time_ns(advanced_time);
64}
65
66static void check_set_count(gconstpointer arg)
67{
68 const uint8_t *policy = arg;
91b37aea 69 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
5b262bb6
DO
70
71 triggered = false;
72
91b37aea 73 ptimer_transaction_begin(ptimer);
5b262bb6 74 ptimer_set_count(ptimer, 1000);
91b37aea 75 ptimer_transaction_commit(ptimer);
5b262bb6
DO
76 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 1000);
77 g_assert_false(triggered);
072bdb07 78 ptimer_free(ptimer);
5b262bb6
DO
79}
80
81static void check_set_limit(gconstpointer arg)
82{
83 const uint8_t *policy = arg;
91b37aea 84 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
5b262bb6
DO
85
86 triggered = false;
87
91b37aea 88 ptimer_transaction_begin(ptimer);
5b262bb6 89 ptimer_set_limit(ptimer, 1000, 0);
91b37aea 90 ptimer_transaction_commit(ptimer);
5b262bb6
DO
91 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
92 g_assert_cmpuint(ptimer_get_limit(ptimer), ==, 1000);
93 g_assert_false(triggered);
94
91b37aea 95 ptimer_transaction_begin(ptimer);
5b262bb6 96 ptimer_set_limit(ptimer, 2000, 1);
91b37aea 97 ptimer_transaction_commit(ptimer);
5b262bb6
DO
98 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 2000);
99 g_assert_cmpuint(ptimer_get_limit(ptimer), ==, 2000);
100 g_assert_false(triggered);
072bdb07 101 ptimer_free(ptimer);
5b262bb6
DO
102}
103
104static void check_oneshot(gconstpointer arg)
105{
106 const uint8_t *policy = arg;
91b37aea 107 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
057516fe 108 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
5b262bb6
DO
109
110 triggered = false;
111
91b37aea 112 ptimer_transaction_begin(ptimer);
5b262bb6
DO
113 ptimer_set_period(ptimer, 2000000);
114 ptimer_set_count(ptimer, 10);
115 ptimer_run(ptimer, 1);
91b37aea 116 ptimer_transaction_commit(ptimer);
5b262bb6 117
33d44cdf 118 qemu_clock_step(2000000 * 2 + 1);
5b262bb6 119
057516fe 120 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
5b262bb6
DO
121 g_assert_false(triggered);
122
91b37aea 123 ptimer_transaction_begin(ptimer);
5b262bb6 124 ptimer_stop(ptimer);
91b37aea 125 ptimer_transaction_commit(ptimer);
5b262bb6 126
057516fe 127 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
5b262bb6
DO
128 g_assert_false(triggered);
129
130 qemu_clock_step(2000000 * 11);
131
057516fe 132 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
5b262bb6
DO
133 g_assert_false(triggered);
134
91b37aea 135 ptimer_transaction_begin(ptimer);
5b262bb6 136 ptimer_run(ptimer, 1);
91b37aea 137 ptimer_transaction_commit(ptimer);
5b262bb6 138
33d44cdf 139 qemu_clock_step(2000000 * 7 + 1);
5b262bb6 140
057516fe 141 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
5b262bb6 142
057516fe
DO
143 if (no_round_down) {
144 g_assert_false(triggered);
145 } else {
146 g_assert_true(triggered);
147
148 triggered = false;
149 }
5b262bb6
DO
150
151 qemu_clock_step(2000000);
152
153 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
057516fe
DO
154
155 if (no_round_down) {
156 g_assert_true(triggered);
157
158 triggered = false;
159 } else {
160 g_assert_false(triggered);
161 }
5b262bb6
DO
162
163 qemu_clock_step(4000000);
164
165 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
166 g_assert_false(triggered);
167
91b37aea 168 ptimer_transaction_begin(ptimer);
5b262bb6 169 ptimer_set_count(ptimer, 10);
91b37aea 170 ptimer_transaction_commit(ptimer);
5b262bb6 171
33d44cdf 172 qemu_clock_step(20000000 + 1);
5b262bb6
DO
173
174 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
175 g_assert_false(triggered);
176
91b37aea 177 ptimer_transaction_begin(ptimer);
5b262bb6 178 ptimer_set_limit(ptimer, 9, 1);
91b37aea 179 ptimer_transaction_commit(ptimer);
5b262bb6 180
33d44cdf 181 qemu_clock_step(20000000 + 1);
5b262bb6
DO
182
183 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 9);
184 g_assert_false(triggered);
185
91b37aea 186 ptimer_transaction_begin(ptimer);
5b262bb6 187 ptimer_run(ptimer, 1);
91b37aea 188 ptimer_transaction_commit(ptimer);
5b262bb6 189
33d44cdf 190 qemu_clock_step(2000000 + 1);
5b262bb6 191
057516fe 192 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
5b262bb6
DO
193 g_assert_false(triggered);
194
91b37aea 195 ptimer_transaction_begin(ptimer);
5b262bb6 196 ptimer_set_count(ptimer, 20);
91b37aea 197 ptimer_transaction_commit(ptimer);
5b262bb6 198
33d44cdf 199 qemu_clock_step(2000000 * 19 + 1);
5b262bb6 200
057516fe 201 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
5b262bb6
DO
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
91b37aea 209 ptimer_transaction_begin(ptimer);
5b262bb6 210 ptimer_stop(ptimer);
91b37aea 211 ptimer_transaction_commit(ptimer);
5b262bb6
DO
212
213 triggered = false;
214
33d44cdf 215 qemu_clock_step(2000000 * 12 + 1);
5b262bb6
DO
216
217 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
218 g_assert_false(triggered);
072bdb07 219 ptimer_free(ptimer);
5b262bb6
DO
220}
221
222static void check_periodic(gconstpointer arg)
223{
224 const uint8_t *policy = arg;
91b37aea 225 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
293130aa 226 bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
516deb42 227 bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
56700e1a 228 bool no_immediate_reload = (*policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD);
057516fe 229 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
086ede32 230 bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
5b262bb6
DO
231
232 triggered = false;
233
91b37aea 234 ptimer_transaction_begin(ptimer);
5b262bb6
DO
235 ptimer_set_period(ptimer, 2000000);
236 ptimer_set_limit(ptimer, 10, 1);
237 ptimer_run(ptimer, 0);
91b37aea 238 ptimer_transaction_commit(ptimer);
5b262bb6 239
293130aa
DO
240 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
241 g_assert_false(triggered);
242
33d44cdf 243 qemu_clock_step(1);
5b262bb6 244
057516fe 245 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 10 : 9);
293130aa
DO
246 g_assert_false(triggered);
247
33d44cdf 248 qemu_clock_step(2000000 * 10 - 1);
293130aa
DO
249
250 g_assert_cmpuint(ptimer_get_count(ptimer), ==, wrap_policy ? 0 : 10);
251 g_assert_true(triggered);
252
33d44cdf 253 qemu_clock_step(1);
293130aa 254
057516fe
DO
255 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
256 wrap_policy ? 0 : (no_round_down ? 10 : 9));
5b262bb6
DO
257 g_assert_true(triggered);
258
259 triggered = false;
260
261 qemu_clock_step(2000000);
262
057516fe
DO
263 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
264 (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
5b262bb6
DO
265 g_assert_false(triggered);
266
91b37aea 267 ptimer_transaction_begin(ptimer);
5b262bb6 268 ptimer_set_count(ptimer, 20);
91b37aea 269 ptimer_transaction_commit(ptimer);
5b262bb6 270
293130aa
DO
271 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 20);
272 g_assert_false(triggered);
273
33d44cdf 274 qemu_clock_step(1);
293130aa 275
057516fe 276 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 20 : 19);
293130aa
DO
277 g_assert_false(triggered);
278
33d44cdf 279 qemu_clock_step(2000000 * 11 + 1);
5b262bb6 280
057516fe 281 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 9 : 8);
5b262bb6
DO
282 g_assert_false(triggered);
283
284 qemu_clock_step(2000000 * 10);
285
057516fe
DO
286 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
287 (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
293130aa
DO
288 g_assert_true(triggered);
289
290 triggered = false;
291
91b37aea 292 ptimer_transaction_begin(ptimer);
293130aa 293 ptimer_set_count(ptimer, 3);
91b37aea 294 ptimer_transaction_commit(ptimer);
293130aa
DO
295
296 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 3);
297 g_assert_false(triggered);
298
33d44cdf 299 qemu_clock_step(1);
293130aa 300
057516fe 301 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 3 : 2);
293130aa
DO
302 g_assert_false(triggered);
303
304 qemu_clock_step(2000000 * 4);
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_true(triggered);
309
91b37aea 310 ptimer_transaction_begin(ptimer);
5b262bb6 311 ptimer_stop(ptimer);
91b37aea 312 ptimer_transaction_commit(ptimer);
5b262bb6
DO
313 triggered = false;
314
315 qemu_clock_step(2000000);
316
057516fe
DO
317 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
318 (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
5b262bb6
DO
319 g_assert_false(triggered);
320
91b37aea 321 ptimer_transaction_begin(ptimer);
5b262bb6
DO
322 ptimer_set_count(ptimer, 3);
323 ptimer_run(ptimer, 0);
91b37aea 324 ptimer_transaction_commit(ptimer);
5b262bb6 325
33d44cdf 326 qemu_clock_step(2000000 * 3 + 1);
5b262bb6 327
057516fe
DO
328 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
329 wrap_policy ? 0 : (no_round_down ? 10 : 9));
5b262bb6
DO
330 g_assert_true(triggered);
331
332 triggered = false;
333
334 qemu_clock_step(2000000);
335
057516fe
DO
336 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
337 (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
5b262bb6
DO
338 g_assert_false(triggered);
339
91b37aea 340 ptimer_transaction_begin(ptimer);
5b262bb6 341 ptimer_set_count(ptimer, 0);
91b37aea 342 ptimer_transaction_commit(ptimer);
56700e1a
DO
343 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
344 no_immediate_reload ? 0 : 10);
516deb42 345
086ede32 346 if (no_immediate_trigger || trig_only_on_dec) {
516deb42
DO
347 g_assert_false(triggered);
348 } else {
349 g_assert_true(triggered);
350 }
5b262bb6
DO
351
352 triggered = false;
353
33d44cdf 354 qemu_clock_step(1);
5b262bb6 355
56700e1a
DO
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
057516fe 371 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 10 : 9);
293130aa
DO
372 g_assert_false(triggered);
373
374 qemu_clock_step(2000000 * 12);
375
057516fe
DO
376 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
377 (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
5b262bb6
DO
378 g_assert_true(triggered);
379
91b37aea 380 ptimer_transaction_begin(ptimer);
5b262bb6 381 ptimer_stop(ptimer);
91b37aea 382 ptimer_transaction_commit(ptimer);
5b262bb6
DO
383
384 triggered = false;
385
293130aa 386 qemu_clock_step(2000000 * 10);
5b262bb6 387
057516fe
DO
388 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
389 (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
5b262bb6
DO
390 g_assert_false(triggered);
391
91b37aea 392 ptimer_transaction_begin(ptimer);
5b262bb6 393 ptimer_run(ptimer, 0);
91b37aea
PM
394 ptimer_transaction_commit(ptimer);
395
396 ptimer_transaction_begin(ptimer);
5b262bb6 397 ptimer_set_period(ptimer, 0);
91b37aea 398 ptimer_transaction_commit(ptimer);
5b262bb6 399
33d44cdf 400 qemu_clock_step(2000000 + 1);
5b262bb6 401
057516fe
DO
402 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
403 (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
5b262bb6 404 g_assert_false(triggered);
072bdb07 405 ptimer_free(ptimer);
5b262bb6
DO
406}
407
408static void check_on_the_fly_mode_change(gconstpointer arg)
409{
410 const uint8_t *policy = arg;
91b37aea 411 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
293130aa 412 bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
057516fe 413 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
5b262bb6
DO
414
415 triggered = false;
416
91b37aea 417 ptimer_transaction_begin(ptimer);
5b262bb6
DO
418 ptimer_set_period(ptimer, 2000000);
419 ptimer_set_limit(ptimer, 10, 1);
420 ptimer_run(ptimer, 1);
91b37aea 421 ptimer_transaction_commit(ptimer);
5b262bb6 422
33d44cdf 423 qemu_clock_step(2000000 * 9 + 1);
5b262bb6 424
057516fe 425 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
293130aa
DO
426 g_assert_false(triggered);
427
91b37aea 428 ptimer_transaction_begin(ptimer);
5b262bb6 429 ptimer_run(ptimer, 0);
91b37aea 430 ptimer_transaction_commit(ptimer);
5b262bb6 431
057516fe 432 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
5b262bb6
DO
433 g_assert_false(triggered);
434
435 qemu_clock_step(2000000);
436
057516fe
DO
437 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
438 wrap_policy ? 0 : (no_round_down ? 10 : 9));
5b262bb6
DO
439 g_assert_true(triggered);
440
441 triggered = false;
442
443 qemu_clock_step(2000000 * 9);
444
91b37aea 445 ptimer_transaction_begin(ptimer);
5b262bb6 446 ptimer_run(ptimer, 1);
91b37aea 447 ptimer_transaction_commit(ptimer);
5b262bb6 448
057516fe
DO
449 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
450 (no_round_down ? 1 : 0) + (wrap_policy ? 1 : 0));
5b262bb6
DO
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);
072bdb07 457 ptimer_free(ptimer);
5b262bb6
DO
458}
459
460static void check_on_the_fly_period_change(gconstpointer arg)
461{
462 const uint8_t *policy = arg;
91b37aea 463 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
057516fe 464 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
5b262bb6
DO
465
466 triggered = false;
467
91b37aea 468 ptimer_transaction_begin(ptimer);
5b262bb6
DO
469 ptimer_set_period(ptimer, 2000000);
470 ptimer_set_limit(ptimer, 8, 1);
471 ptimer_run(ptimer, 1);
91b37aea 472 ptimer_transaction_commit(ptimer);
5b262bb6 473
33d44cdf 474 qemu_clock_step(2000000 * 4 + 1);
5b262bb6 475
057516fe 476 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
5b262bb6
DO
477 g_assert_false(triggered);
478
91b37aea 479 ptimer_transaction_begin(ptimer);
5b262bb6 480 ptimer_set_period(ptimer, 4000000);
91b37aea 481 ptimer_transaction_commit(ptimer);
057516fe 482 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
5b262bb6 483
33d44cdf 484 qemu_clock_step(4000000 * 2 + 1);
5b262bb6 485
057516fe 486 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 2 : 0);
5b262bb6
DO
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);
072bdb07 493 ptimer_free(ptimer);
5b262bb6
DO
494}
495
496static void check_on_the_fly_freq_change(gconstpointer arg)
497{
498 const uint8_t *policy = arg;
91b37aea 499 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
057516fe 500 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
5b262bb6
DO
501
502 triggered = false;
503
91b37aea 504 ptimer_transaction_begin(ptimer);
5b262bb6
DO
505 ptimer_set_freq(ptimer, 500);
506 ptimer_set_limit(ptimer, 8, 1);
507 ptimer_run(ptimer, 1);
91b37aea 508 ptimer_transaction_commit(ptimer);
5b262bb6 509
33d44cdf 510 qemu_clock_step(2000000 * 4 + 1);
5b262bb6 511
057516fe 512 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
5b262bb6
DO
513 g_assert_false(triggered);
514
91b37aea 515 ptimer_transaction_begin(ptimer);
5b262bb6 516 ptimer_set_freq(ptimer, 250);
91b37aea 517 ptimer_transaction_commit(ptimer);
057516fe 518 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
5b262bb6 519
33d44cdf 520 qemu_clock_step(2000000 * 4 + 1);
5b262bb6 521
057516fe 522 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 2 : 0);
5b262bb6
DO
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);
072bdb07 529 ptimer_free(ptimer);
5b262bb6
DO
530}
531
532static void check_run_with_period_0(gconstpointer arg)
533{
534 const uint8_t *policy = arg;
91b37aea 535 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
5b262bb6
DO
536
537 triggered = false;
538
91b37aea 539 ptimer_transaction_begin(ptimer);
5b262bb6
DO
540 ptimer_set_count(ptimer, 99);
541 ptimer_run(ptimer, 1);
91b37aea 542 ptimer_transaction_commit(ptimer);
5b262bb6
DO
543
544 qemu_clock_step(10 * NANOSECONDS_PER_SECOND);
545
546 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 99);
547 g_assert_false(triggered);
072bdb07 548 ptimer_free(ptimer);
5b262bb6
DO
549}
550
551static void check_run_with_delta_0(gconstpointer arg)
552{
553 const uint8_t *policy = arg;
91b37aea 554 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
293130aa 555 bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
516deb42 556 bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
56700e1a 557 bool no_immediate_reload = (*policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD);
057516fe 558 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
086ede32 559 bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
5b262bb6
DO
560
561 triggered = false;
562
91b37aea 563 ptimer_transaction_begin(ptimer);
5b262bb6
DO
564 ptimer_set_period(ptimer, 2000000);
565 ptimer_set_limit(ptimer, 99, 0);
566 ptimer_run(ptimer, 1);
91b37aea 567 ptimer_transaction_commit(ptimer);
56700e1a
DO
568 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
569 no_immediate_reload ? 0 : 99);
516deb42 570
086ede32 571 if (no_immediate_trigger || trig_only_on_dec) {
516deb42
DO
572 g_assert_false(triggered);
573 } else {
574 g_assert_true(triggered);
575 }
5b262bb6
DO
576
577 triggered = false;
578
56700e1a 579 if (no_immediate_trigger || no_immediate_reload) {
33d44cdf 580 qemu_clock_step(2000000 + 1);
516deb42 581
56700e1a 582 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
057516fe 583 no_immediate_reload ? 0 : (no_round_down ? 98 : 97));
56700e1a
DO
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 }
516deb42 592
91b37aea 593 ptimer_transaction_begin(ptimer);
516deb42
DO
594 ptimer_set_count(ptimer, 99);
595 ptimer_run(ptimer, 1);
91b37aea 596 ptimer_transaction_commit(ptimer);
516deb42
DO
597 }
598
33d44cdf 599 qemu_clock_step(2000000 + 1);
5b262bb6 600
057516fe 601 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 98 : 97);
5b262bb6
DO
602 g_assert_false(triggered);
603
604 qemu_clock_step(2000000 * 97);
605
057516fe 606 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
5b262bb6
DO
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
91b37aea 616 ptimer_transaction_begin(ptimer);
5b262bb6
DO
617 ptimer_set_count(ptimer, 0);
618 ptimer_run(ptimer, 0);
91b37aea 619 ptimer_transaction_commit(ptimer);
56700e1a
DO
620 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
621 no_immediate_reload ? 0 : 99);
516deb42 622
086ede32 623 if (no_immediate_trigger || trig_only_on_dec) {
516deb42
DO
624 g_assert_false(triggered);
625 } else {
626 g_assert_true(triggered);
627 }
5b262bb6
DO
628
629 triggered = false;
630
33d44cdf 631 qemu_clock_step(1);
293130aa 632
56700e1a
DO
633 if (no_immediate_reload) {
634 qemu_clock_step(2000000);
635 }
636
057516fe 637 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 99 : 98);
56700e1a
DO
638
639 if (no_immediate_reload && no_immediate_trigger) {
640 g_assert_true(triggered);
641 } else {
642 g_assert_false(triggered);
643 }
293130aa
DO
644
645 triggered = false;
646
647 qemu_clock_step(2000000);
5b262bb6 648
057516fe 649 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 98 : 97);
5b262bb6
DO
650 g_assert_false(triggered);
651
652 qemu_clock_step(2000000 * 98);
653
057516fe
DO
654 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
655 wrap_policy ? 0 : (no_round_down ? 99 : 98));
5b262bb6
DO
656 g_assert_true(triggered);
657
91b37aea 658 ptimer_transaction_begin(ptimer);
5b262bb6 659 ptimer_stop(ptimer);
91b37aea 660 ptimer_transaction_commit(ptimer);
072bdb07 661 ptimer_free(ptimer);
5b262bb6
DO
662}
663
664static void check_periodic_with_load_0(gconstpointer arg)
665{
666 const uint8_t *policy = arg;
91b37aea 667 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
2e74583b 668 bool continuous_trigger = (*policy & PTIMER_POLICY_CONTINUOUS_TRIGGER);
516deb42 669 bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
086ede32 670 bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
5b262bb6
DO
671
672 triggered = false;
673
91b37aea 674 ptimer_transaction_begin(ptimer);
5b262bb6
DO
675 ptimer_set_period(ptimer, 2000000);
676 ptimer_run(ptimer, 0);
91b37aea 677 ptimer_transaction_commit(ptimer);
5b262bb6
DO
678
679 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
516deb42 680
086ede32 681 if (no_immediate_trigger || trig_only_on_dec) {
516deb42
DO
682 g_assert_false(triggered);
683 } else {
684 g_assert_true(triggered);
685 }
5b262bb6
DO
686
687 triggered = false;
688
33d44cdf 689 qemu_clock_step(2000000 + 1);
5b262bb6
DO
690
691 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
2e74583b 692
516deb42 693 if (continuous_trigger || no_immediate_trigger) {
2e74583b
DO
694 g_assert_true(triggered);
695 } else {
696 g_assert_false(triggered);
697 }
5b262bb6 698
293130aa
DO
699 triggered = false;
700
91b37aea 701 ptimer_transaction_begin(ptimer);
293130aa
DO
702 ptimer_set_count(ptimer, 10);
703 ptimer_run(ptimer, 0);
91b37aea 704 ptimer_transaction_commit(ptimer);
293130aa 705
33d44cdf 706 qemu_clock_step(2000000 * 10 + 1);
293130aa
DO
707
708 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
709 g_assert_true(triggered);
710
711 triggered = false;
712
33d44cdf 713 qemu_clock_step(2000000 + 1);
293130aa
DO
714
715 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
2e74583b
DO
716
717 if (continuous_trigger) {
718 g_assert_true(triggered);
719 } else {
720 g_assert_false(triggered);
721 }
293130aa 722
91b37aea 723 ptimer_transaction_begin(ptimer);
5b262bb6 724 ptimer_stop(ptimer);
91b37aea 725 ptimer_transaction_commit(ptimer);
072bdb07 726 ptimer_free(ptimer);
5b262bb6
DO
727}
728
729static void check_oneshot_with_load_0(gconstpointer arg)
730{
731 const uint8_t *policy = arg;
91b37aea 732 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
516deb42 733 bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
086ede32 734 bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
5b262bb6
DO
735
736 triggered = false;
737
91b37aea 738 ptimer_transaction_begin(ptimer);
5b262bb6
DO
739 ptimer_set_period(ptimer, 2000000);
740 ptimer_run(ptimer, 1);
91b37aea 741 ptimer_transaction_commit(ptimer);
5b262bb6
DO
742
743 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
516deb42 744
086ede32 745 if (no_immediate_trigger || trig_only_on_dec) {
516deb42
DO
746 g_assert_false(triggered);
747 } else {
748 g_assert_true(triggered);
749 }
5b262bb6
DO
750
751 triggered = false;
752
33d44cdf 753 qemu_clock_step(2000000 + 1);
5b262bb6
DO
754
755 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
516deb42
DO
756
757 if (no_immediate_trigger) {
758 g_assert_true(triggered);
759 } else {
760 g_assert_false(triggered);
761 }
072bdb07
MAL
762
763 ptimer_free(ptimer);
5b262bb6
DO
764}
765
766static void add_ptimer_tests(uint8_t policy)
767{
072bdb07
MAL
768 char policy_name[256] = "";
769 char *tmp;
5b262bb6
DO
770
771 if (policy == PTIMER_POLICY_DEFAULT) {
772 g_sprintf(policy_name, "default");
773 }
774
293130aa
DO
775 if (policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD) {
776 g_strlcat(policy_name, "wrap_after_one_period,", 256);
777 }
778
2e74583b
DO
779 if (policy & PTIMER_POLICY_CONTINUOUS_TRIGGER) {
780 g_strlcat(policy_name, "continuous_trigger,", 256);
781 }
782
516deb42
DO
783 if (policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER) {
784 g_strlcat(policy_name, "no_immediate_trigger,", 256);
785 }
786
56700e1a
DO
787 if (policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD) {
788 g_strlcat(policy_name, "no_immediate_reload,", 256);
789 }
790
057516fe
DO
791 if (policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN) {
792 g_strlcat(policy_name, "no_counter_rounddown,", 256);
793 }
794
086ede32
PM
795 if (policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) {
796 g_strlcat(policy_name, "trigger_only_on_decrement,", 256);
797 }
798
072bdb07
MAL
799 g_test_add_data_func_full(
800 tmp = g_strdup_printf("/ptimer/set_count policy=%s", policy_name),
801 g_memdup(&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_memdup(&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_memdup(&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_memdup(&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_memdup(&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_memdup(&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_memdup(&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_memdup(&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_memdup(&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_memdup(&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_memdup(&policy, 1), check_oneshot_with_load_0, g_free);
859 g_free(tmp);
5b262bb6
DO
860}
861
293130aa
DO
862static void add_all_ptimer_policies_comb_tests(void)
863{
086ede32 864 int last_policy = PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT;
293130aa
DO
865 int policy = PTIMER_POLICY_DEFAULT;
866
867 for (; policy < (last_policy << 1); policy++) {
086ede32
PM
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 }
293130aa
DO
873 add_ptimer_tests(policy);
874 }
875}
876
5b262bb6
DO
877int 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
293130aa 887 add_all_ptimer_policies_comb_tests();
5b262bb6
DO
888
889 qtest_allowed = true;
890
891 return g_test_run();
892}