]> git.proxmox.com Git - mirror_qemu.git/blame - tests/ptimer-test.c
tests/numa: Add case for QMP build HMAT
[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
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{
dcb15780
PD
53 int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
54 QEMU_TIMER_ATTR_ALL);
5b262bb6
DO
55 int64_t advanced_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns;
56
57 while (deadline != -1 && deadline <= advanced_time) {
58 ptimer_test_set_qemu_time_ns(deadline);
59 ptimer_test_expire_qemu_timers(deadline, QEMU_CLOCK_VIRTUAL);
dcb15780
PD
60 deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
61 QEMU_TIMER_ATTR_ALL);
5b262bb6
DO
62 }
63
64 ptimer_test_set_qemu_time_ns(advanced_time);
65}
66
67static void check_set_count(gconstpointer arg)
68{
69 const uint8_t *policy = arg;
91b37aea 70 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
5b262bb6
DO
71
72 triggered = false;
73
91b37aea 74 ptimer_transaction_begin(ptimer);
5b262bb6 75 ptimer_set_count(ptimer, 1000);
91b37aea 76 ptimer_transaction_commit(ptimer);
5b262bb6
DO
77 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 1000);
78 g_assert_false(triggered);
072bdb07 79 ptimer_free(ptimer);
5b262bb6
DO
80}
81
82static void check_set_limit(gconstpointer arg)
83{
84 const uint8_t *policy = arg;
91b37aea 85 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
5b262bb6
DO
86
87 triggered = false;
88
91b37aea 89 ptimer_transaction_begin(ptimer);
5b262bb6 90 ptimer_set_limit(ptimer, 1000, 0);
91b37aea 91 ptimer_transaction_commit(ptimer);
5b262bb6
DO
92 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
93 g_assert_cmpuint(ptimer_get_limit(ptimer), ==, 1000);
94 g_assert_false(triggered);
95
91b37aea 96 ptimer_transaction_begin(ptimer);
5b262bb6 97 ptimer_set_limit(ptimer, 2000, 1);
91b37aea 98 ptimer_transaction_commit(ptimer);
5b262bb6
DO
99 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 2000);
100 g_assert_cmpuint(ptimer_get_limit(ptimer), ==, 2000);
101 g_assert_false(triggered);
072bdb07 102 ptimer_free(ptimer);
5b262bb6
DO
103}
104
105static void check_oneshot(gconstpointer arg)
106{
107 const uint8_t *policy = arg;
91b37aea 108 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
057516fe 109 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
5b262bb6
DO
110
111 triggered = false;
112
91b37aea 113 ptimer_transaction_begin(ptimer);
5b262bb6
DO
114 ptimer_set_period(ptimer, 2000000);
115 ptimer_set_count(ptimer, 10);
116 ptimer_run(ptimer, 1);
91b37aea 117 ptimer_transaction_commit(ptimer);
5b262bb6 118
33d44cdf 119 qemu_clock_step(2000000 * 2 + 1);
5b262bb6 120
057516fe 121 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
5b262bb6
DO
122 g_assert_false(triggered);
123
91b37aea 124 ptimer_transaction_begin(ptimer);
5b262bb6 125 ptimer_stop(ptimer);
91b37aea 126 ptimer_transaction_commit(ptimer);
5b262bb6 127
057516fe 128 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
5b262bb6
DO
129 g_assert_false(triggered);
130
131 qemu_clock_step(2000000 * 11);
132
057516fe 133 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
5b262bb6
DO
134 g_assert_false(triggered);
135
91b37aea 136 ptimer_transaction_begin(ptimer);
5b262bb6 137 ptimer_run(ptimer, 1);
91b37aea 138 ptimer_transaction_commit(ptimer);
5b262bb6 139
33d44cdf 140 qemu_clock_step(2000000 * 7 + 1);
5b262bb6 141
057516fe 142 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
5b262bb6 143
057516fe
DO
144 if (no_round_down) {
145 g_assert_false(triggered);
146 } else {
147 g_assert_true(triggered);
148
149 triggered = false;
150 }
5b262bb6
DO
151
152 qemu_clock_step(2000000);
153
154 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
057516fe
DO
155
156 if (no_round_down) {
157 g_assert_true(triggered);
158
159 triggered = false;
160 } else {
161 g_assert_false(triggered);
162 }
5b262bb6
DO
163
164 qemu_clock_step(4000000);
165
166 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
167 g_assert_false(triggered);
168
91b37aea 169 ptimer_transaction_begin(ptimer);
5b262bb6 170 ptimer_set_count(ptimer, 10);
91b37aea 171 ptimer_transaction_commit(ptimer);
5b262bb6 172
33d44cdf 173 qemu_clock_step(20000000 + 1);
5b262bb6
DO
174
175 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
176 g_assert_false(triggered);
177
91b37aea 178 ptimer_transaction_begin(ptimer);
5b262bb6 179 ptimer_set_limit(ptimer, 9, 1);
91b37aea 180 ptimer_transaction_commit(ptimer);
5b262bb6 181
33d44cdf 182 qemu_clock_step(20000000 + 1);
5b262bb6
DO
183
184 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 9);
185 g_assert_false(triggered);
186
91b37aea 187 ptimer_transaction_begin(ptimer);
5b262bb6 188 ptimer_run(ptimer, 1);
91b37aea 189 ptimer_transaction_commit(ptimer);
5b262bb6 190
33d44cdf 191 qemu_clock_step(2000000 + 1);
5b262bb6 192
057516fe 193 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
5b262bb6
DO
194 g_assert_false(triggered);
195
91b37aea 196 ptimer_transaction_begin(ptimer);
5b262bb6 197 ptimer_set_count(ptimer, 20);
91b37aea 198 ptimer_transaction_commit(ptimer);
5b262bb6 199
33d44cdf 200 qemu_clock_step(2000000 * 19 + 1);
5b262bb6 201
057516fe 202 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
5b262bb6
DO
203 g_assert_false(triggered);
204
205 qemu_clock_step(2000000);
206
207 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
208 g_assert_true(triggered);
209
91b37aea 210 ptimer_transaction_begin(ptimer);
5b262bb6 211 ptimer_stop(ptimer);
91b37aea 212 ptimer_transaction_commit(ptimer);
5b262bb6
DO
213
214 triggered = false;
215
33d44cdf 216 qemu_clock_step(2000000 * 12 + 1);
5b262bb6
DO
217
218 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
219 g_assert_false(triggered);
072bdb07 220 ptimer_free(ptimer);
5b262bb6
DO
221}
222
223static void check_periodic(gconstpointer arg)
224{
225 const uint8_t *policy = arg;
91b37aea 226 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
293130aa 227 bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
516deb42 228 bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
56700e1a 229 bool no_immediate_reload = (*policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD);
057516fe 230 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
086ede32 231 bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
5b262bb6
DO
232
233 triggered = false;
234
91b37aea 235 ptimer_transaction_begin(ptimer);
5b262bb6
DO
236 ptimer_set_period(ptimer, 2000000);
237 ptimer_set_limit(ptimer, 10, 1);
238 ptimer_run(ptimer, 0);
91b37aea 239 ptimer_transaction_commit(ptimer);
5b262bb6 240
293130aa
DO
241 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
242 g_assert_false(triggered);
243
33d44cdf 244 qemu_clock_step(1);
5b262bb6 245
057516fe 246 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 10 : 9);
293130aa
DO
247 g_assert_false(triggered);
248
33d44cdf 249 qemu_clock_step(2000000 * 10 - 1);
293130aa
DO
250
251 g_assert_cmpuint(ptimer_get_count(ptimer), ==, wrap_policy ? 0 : 10);
252 g_assert_true(triggered);
253
33d44cdf 254 qemu_clock_step(1);
293130aa 255
057516fe
DO
256 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
257 wrap_policy ? 0 : (no_round_down ? 10 : 9));
5b262bb6
DO
258 g_assert_true(triggered);
259
260 triggered = false;
261
262 qemu_clock_step(2000000);
263
057516fe
DO
264 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
265 (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
5b262bb6
DO
266 g_assert_false(triggered);
267
91b37aea 268 ptimer_transaction_begin(ptimer);
5b262bb6 269 ptimer_set_count(ptimer, 20);
91b37aea 270 ptimer_transaction_commit(ptimer);
5b262bb6 271
293130aa
DO
272 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 20);
273 g_assert_false(triggered);
274
33d44cdf 275 qemu_clock_step(1);
293130aa 276
057516fe 277 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 20 : 19);
293130aa
DO
278 g_assert_false(triggered);
279
33d44cdf 280 qemu_clock_step(2000000 * 11 + 1);
5b262bb6 281
057516fe 282 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 9 : 8);
5b262bb6
DO
283 g_assert_false(triggered);
284
285 qemu_clock_step(2000000 * 10);
286
057516fe
DO
287 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
288 (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
293130aa
DO
289 g_assert_true(triggered);
290
291 triggered = false;
292
91b37aea 293 ptimer_transaction_begin(ptimer);
293130aa 294 ptimer_set_count(ptimer, 3);
91b37aea 295 ptimer_transaction_commit(ptimer);
293130aa
DO
296
297 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 3);
298 g_assert_false(triggered);
299
33d44cdf 300 qemu_clock_step(1);
293130aa 301
057516fe 302 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 3 : 2);
293130aa
DO
303 g_assert_false(triggered);
304
305 qemu_clock_step(2000000 * 4);
306
057516fe
DO
307 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
308 (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
5b262bb6
DO
309 g_assert_true(triggered);
310
91b37aea 311 ptimer_transaction_begin(ptimer);
5b262bb6 312 ptimer_stop(ptimer);
91b37aea 313 ptimer_transaction_commit(ptimer);
5b262bb6
DO
314 triggered = false;
315
316 qemu_clock_step(2000000);
317
057516fe
DO
318 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
319 (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
5b262bb6
DO
320 g_assert_false(triggered);
321
91b37aea 322 ptimer_transaction_begin(ptimer);
5b262bb6
DO
323 ptimer_set_count(ptimer, 3);
324 ptimer_run(ptimer, 0);
91b37aea 325 ptimer_transaction_commit(ptimer);
5b262bb6 326
33d44cdf 327 qemu_clock_step(2000000 * 3 + 1);
5b262bb6 328
057516fe
DO
329 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
330 wrap_policy ? 0 : (no_round_down ? 10 : 9));
5b262bb6
DO
331 g_assert_true(triggered);
332
333 triggered = false;
334
335 qemu_clock_step(2000000);
336
057516fe
DO
337 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
338 (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
5b262bb6
DO
339 g_assert_false(triggered);
340
91b37aea 341 ptimer_transaction_begin(ptimer);
5b262bb6 342 ptimer_set_count(ptimer, 0);
91b37aea 343 ptimer_transaction_commit(ptimer);
56700e1a
DO
344 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
345 no_immediate_reload ? 0 : 10);
516deb42 346
086ede32 347 if (no_immediate_trigger || trig_only_on_dec) {
516deb42
DO
348 g_assert_false(triggered);
349 } else {
350 g_assert_true(triggered);
351 }
5b262bb6
DO
352
353 triggered = false;
354
33d44cdf 355 qemu_clock_step(1);
5b262bb6 356
56700e1a
DO
357 if (no_immediate_reload) {
358 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
359 g_assert_false(triggered);
360
361 qemu_clock_step(2000000);
362
363 if (no_immediate_trigger) {
364 g_assert_true(triggered);
365 } else {
366 g_assert_false(triggered);
367 }
368
369 triggered = false;
370 }
371
057516fe 372 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 10 : 9);
293130aa
DO
373 g_assert_false(triggered);
374
375 qemu_clock_step(2000000 * 12);
376
057516fe
DO
377 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
378 (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
5b262bb6
DO
379 g_assert_true(triggered);
380
91b37aea 381 ptimer_transaction_begin(ptimer);
5b262bb6 382 ptimer_stop(ptimer);
91b37aea 383 ptimer_transaction_commit(ptimer);
5b262bb6
DO
384
385 triggered = false;
386
293130aa 387 qemu_clock_step(2000000 * 10);
5b262bb6 388
057516fe
DO
389 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
390 (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
5b262bb6
DO
391 g_assert_false(triggered);
392
91b37aea 393 ptimer_transaction_begin(ptimer);
5b262bb6 394 ptimer_run(ptimer, 0);
91b37aea
PM
395 ptimer_transaction_commit(ptimer);
396
397 ptimer_transaction_begin(ptimer);
5b262bb6 398 ptimer_set_period(ptimer, 0);
91b37aea 399 ptimer_transaction_commit(ptimer);
5b262bb6 400
33d44cdf 401 qemu_clock_step(2000000 + 1);
5b262bb6 402
057516fe
DO
403 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
404 (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
5b262bb6 405 g_assert_false(triggered);
072bdb07 406 ptimer_free(ptimer);
5b262bb6
DO
407}
408
409static void check_on_the_fly_mode_change(gconstpointer arg)
410{
411 const uint8_t *policy = arg;
91b37aea 412 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
293130aa 413 bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
057516fe 414 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
5b262bb6
DO
415
416 triggered = false;
417
91b37aea 418 ptimer_transaction_begin(ptimer);
5b262bb6
DO
419 ptimer_set_period(ptimer, 2000000);
420 ptimer_set_limit(ptimer, 10, 1);
421 ptimer_run(ptimer, 1);
91b37aea 422 ptimer_transaction_commit(ptimer);
5b262bb6 423
33d44cdf 424 qemu_clock_step(2000000 * 9 + 1);
5b262bb6 425
057516fe 426 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
293130aa
DO
427 g_assert_false(triggered);
428
91b37aea 429 ptimer_transaction_begin(ptimer);
5b262bb6 430 ptimer_run(ptimer, 0);
91b37aea 431 ptimer_transaction_commit(ptimer);
5b262bb6 432
057516fe 433 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
5b262bb6
DO
434 g_assert_false(triggered);
435
436 qemu_clock_step(2000000);
437
057516fe
DO
438 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
439 wrap_policy ? 0 : (no_round_down ? 10 : 9));
5b262bb6
DO
440 g_assert_true(triggered);
441
442 triggered = false;
443
444 qemu_clock_step(2000000 * 9);
445
91b37aea 446 ptimer_transaction_begin(ptimer);
5b262bb6 447 ptimer_run(ptimer, 1);
91b37aea 448 ptimer_transaction_commit(ptimer);
5b262bb6 449
057516fe
DO
450 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
451 (no_round_down ? 1 : 0) + (wrap_policy ? 1 : 0));
5b262bb6
DO
452 g_assert_false(triggered);
453
454 qemu_clock_step(2000000 * 3);
455
456 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
457 g_assert_true(triggered);
072bdb07 458 ptimer_free(ptimer);
5b262bb6
DO
459}
460
461static void check_on_the_fly_period_change(gconstpointer arg)
462{
463 const uint8_t *policy = arg;
91b37aea 464 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
057516fe 465 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
5b262bb6
DO
466
467 triggered = false;
468
91b37aea 469 ptimer_transaction_begin(ptimer);
5b262bb6
DO
470 ptimer_set_period(ptimer, 2000000);
471 ptimer_set_limit(ptimer, 8, 1);
472 ptimer_run(ptimer, 1);
91b37aea 473 ptimer_transaction_commit(ptimer);
5b262bb6 474
33d44cdf 475 qemu_clock_step(2000000 * 4 + 1);
5b262bb6 476
057516fe 477 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
5b262bb6
DO
478 g_assert_false(triggered);
479
91b37aea 480 ptimer_transaction_begin(ptimer);
5b262bb6 481 ptimer_set_period(ptimer, 4000000);
91b37aea 482 ptimer_transaction_commit(ptimer);
057516fe 483 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
5b262bb6 484
33d44cdf 485 qemu_clock_step(4000000 * 2 + 1);
5b262bb6 486
057516fe 487 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 2 : 0);
5b262bb6
DO
488 g_assert_false(triggered);
489
490 qemu_clock_step(4000000 * 2);
491
492 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
493 g_assert_true(triggered);
072bdb07 494 ptimer_free(ptimer);
5b262bb6
DO
495}
496
497static void check_on_the_fly_freq_change(gconstpointer arg)
498{
499 const uint8_t *policy = arg;
91b37aea 500 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
057516fe 501 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
5b262bb6
DO
502
503 triggered = false;
504
91b37aea 505 ptimer_transaction_begin(ptimer);
5b262bb6
DO
506 ptimer_set_freq(ptimer, 500);
507 ptimer_set_limit(ptimer, 8, 1);
508 ptimer_run(ptimer, 1);
91b37aea 509 ptimer_transaction_commit(ptimer);
5b262bb6 510
33d44cdf 511 qemu_clock_step(2000000 * 4 + 1);
5b262bb6 512
057516fe 513 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
5b262bb6
DO
514 g_assert_false(triggered);
515
91b37aea 516 ptimer_transaction_begin(ptimer);
5b262bb6 517 ptimer_set_freq(ptimer, 250);
91b37aea 518 ptimer_transaction_commit(ptimer);
057516fe 519 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
5b262bb6 520
33d44cdf 521 qemu_clock_step(2000000 * 4 + 1);
5b262bb6 522
057516fe 523 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 2 : 0);
5b262bb6
DO
524 g_assert_false(triggered);
525
526 qemu_clock_step(2000000 * 4);
527
528 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
529 g_assert_true(triggered);
072bdb07 530 ptimer_free(ptimer);
5b262bb6
DO
531}
532
533static void check_run_with_period_0(gconstpointer arg)
534{
535 const uint8_t *policy = arg;
91b37aea 536 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
5b262bb6
DO
537
538 triggered = false;
539
91b37aea 540 ptimer_transaction_begin(ptimer);
5b262bb6
DO
541 ptimer_set_count(ptimer, 99);
542 ptimer_run(ptimer, 1);
91b37aea 543 ptimer_transaction_commit(ptimer);
5b262bb6
DO
544
545 qemu_clock_step(10 * NANOSECONDS_PER_SECOND);
546
547 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 99);
548 g_assert_false(triggered);
072bdb07 549 ptimer_free(ptimer);
5b262bb6
DO
550}
551
552static void check_run_with_delta_0(gconstpointer arg)
553{
554 const uint8_t *policy = arg;
91b37aea 555 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
293130aa 556 bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
516deb42 557 bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
56700e1a 558 bool no_immediate_reload = (*policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD);
057516fe 559 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
086ede32 560 bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
5b262bb6
DO
561
562 triggered = false;
563
91b37aea 564 ptimer_transaction_begin(ptimer);
5b262bb6
DO
565 ptimer_set_period(ptimer, 2000000);
566 ptimer_set_limit(ptimer, 99, 0);
567 ptimer_run(ptimer, 1);
91b37aea 568 ptimer_transaction_commit(ptimer);
56700e1a
DO
569 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
570 no_immediate_reload ? 0 : 99);
516deb42 571
086ede32 572 if (no_immediate_trigger || trig_only_on_dec) {
516deb42
DO
573 g_assert_false(triggered);
574 } else {
575 g_assert_true(triggered);
576 }
5b262bb6
DO
577
578 triggered = false;
579
56700e1a 580 if (no_immediate_trigger || no_immediate_reload) {
33d44cdf 581 qemu_clock_step(2000000 + 1);
516deb42 582
56700e1a 583 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
057516fe 584 no_immediate_reload ? 0 : (no_round_down ? 98 : 97));
56700e1a
DO
585
586 if (no_immediate_trigger && no_immediate_reload) {
587 g_assert_true(triggered);
588
589 triggered = false;
590 } else {
591 g_assert_false(triggered);
592 }
516deb42 593
91b37aea 594 ptimer_transaction_begin(ptimer);
516deb42
DO
595 ptimer_set_count(ptimer, 99);
596 ptimer_run(ptimer, 1);
91b37aea 597 ptimer_transaction_commit(ptimer);
516deb42
DO
598 }
599
33d44cdf 600 qemu_clock_step(2000000 + 1);
5b262bb6 601
057516fe 602 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 98 : 97);
5b262bb6
DO
603 g_assert_false(triggered);
604
605 qemu_clock_step(2000000 * 97);
606
057516fe 607 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
5b262bb6
DO
608 g_assert_false(triggered);
609
610 qemu_clock_step(2000000 * 2);
611
612 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
613 g_assert_true(triggered);
614
615 triggered = false;
616
91b37aea 617 ptimer_transaction_begin(ptimer);
5b262bb6
DO
618 ptimer_set_count(ptimer, 0);
619 ptimer_run(ptimer, 0);
91b37aea 620 ptimer_transaction_commit(ptimer);
56700e1a
DO
621 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
622 no_immediate_reload ? 0 : 99);
516deb42 623
086ede32 624 if (no_immediate_trigger || trig_only_on_dec) {
516deb42
DO
625 g_assert_false(triggered);
626 } else {
627 g_assert_true(triggered);
628 }
5b262bb6
DO
629
630 triggered = false;
631
33d44cdf 632 qemu_clock_step(1);
293130aa 633
56700e1a
DO
634 if (no_immediate_reload) {
635 qemu_clock_step(2000000);
636 }
637
057516fe 638 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 99 : 98);
56700e1a
DO
639
640 if (no_immediate_reload && no_immediate_trigger) {
641 g_assert_true(triggered);
642 } else {
643 g_assert_false(triggered);
644 }
293130aa
DO
645
646 triggered = false;
647
648 qemu_clock_step(2000000);
5b262bb6 649
057516fe 650 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 98 : 97);
5b262bb6
DO
651 g_assert_false(triggered);
652
653 qemu_clock_step(2000000 * 98);
654
057516fe
DO
655 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
656 wrap_policy ? 0 : (no_round_down ? 99 : 98));
5b262bb6
DO
657 g_assert_true(triggered);
658
91b37aea 659 ptimer_transaction_begin(ptimer);
5b262bb6 660 ptimer_stop(ptimer);
91b37aea 661 ptimer_transaction_commit(ptimer);
072bdb07 662 ptimer_free(ptimer);
5b262bb6
DO
663}
664
665static void check_periodic_with_load_0(gconstpointer arg)
666{
667 const uint8_t *policy = arg;
91b37aea 668 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
2e74583b 669 bool continuous_trigger = (*policy & PTIMER_POLICY_CONTINUOUS_TRIGGER);
516deb42 670 bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
086ede32 671 bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
5b262bb6
DO
672
673 triggered = false;
674
91b37aea 675 ptimer_transaction_begin(ptimer);
5b262bb6
DO
676 ptimer_set_period(ptimer, 2000000);
677 ptimer_run(ptimer, 0);
91b37aea 678 ptimer_transaction_commit(ptimer);
5b262bb6
DO
679
680 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
516deb42 681
086ede32 682 if (no_immediate_trigger || trig_only_on_dec) {
516deb42
DO
683 g_assert_false(triggered);
684 } else {
685 g_assert_true(triggered);
686 }
5b262bb6
DO
687
688 triggered = false;
689
33d44cdf 690 qemu_clock_step(2000000 + 1);
5b262bb6
DO
691
692 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
2e74583b 693
516deb42 694 if (continuous_trigger || no_immediate_trigger) {
2e74583b
DO
695 g_assert_true(triggered);
696 } else {
697 g_assert_false(triggered);
698 }
5b262bb6 699
293130aa
DO
700 triggered = false;
701
91b37aea 702 ptimer_transaction_begin(ptimer);
293130aa
DO
703 ptimer_set_count(ptimer, 10);
704 ptimer_run(ptimer, 0);
91b37aea 705 ptimer_transaction_commit(ptimer);
293130aa 706
33d44cdf 707 qemu_clock_step(2000000 * 10 + 1);
293130aa
DO
708
709 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
710 g_assert_true(triggered);
711
712 triggered = false;
713
33d44cdf 714 qemu_clock_step(2000000 + 1);
293130aa
DO
715
716 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
2e74583b
DO
717
718 if (continuous_trigger) {
719 g_assert_true(triggered);
720 } else {
721 g_assert_false(triggered);
722 }
293130aa 723
91b37aea 724 ptimer_transaction_begin(ptimer);
5b262bb6 725 ptimer_stop(ptimer);
91b37aea 726 ptimer_transaction_commit(ptimer);
072bdb07 727 ptimer_free(ptimer);
5b262bb6
DO
728}
729
730static void check_oneshot_with_load_0(gconstpointer arg)
731{
732 const uint8_t *policy = arg;
91b37aea 733 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
516deb42 734 bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
086ede32 735 bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
5b262bb6
DO
736
737 triggered = false;
738
91b37aea 739 ptimer_transaction_begin(ptimer);
5b262bb6
DO
740 ptimer_set_period(ptimer, 2000000);
741 ptimer_run(ptimer, 1);
91b37aea 742 ptimer_transaction_commit(ptimer);
5b262bb6
DO
743
744 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
516deb42 745
086ede32 746 if (no_immediate_trigger || trig_only_on_dec) {
516deb42
DO
747 g_assert_false(triggered);
748 } else {
749 g_assert_true(triggered);
750 }
5b262bb6
DO
751
752 triggered = false;
753
33d44cdf 754 qemu_clock_step(2000000 + 1);
5b262bb6
DO
755
756 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
516deb42
DO
757
758 if (no_immediate_trigger) {
759 g_assert_true(triggered);
760 } else {
761 g_assert_false(triggered);
762 }
072bdb07
MAL
763
764 ptimer_free(ptimer);
5b262bb6
DO
765}
766
767static void add_ptimer_tests(uint8_t policy)
768{
072bdb07
MAL
769 char policy_name[256] = "";
770 char *tmp;
5b262bb6
DO
771
772 if (policy == PTIMER_POLICY_DEFAULT) {
773 g_sprintf(policy_name, "default");
774 }
775
293130aa
DO
776 if (policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD) {
777 g_strlcat(policy_name, "wrap_after_one_period,", 256);
778 }
779
2e74583b
DO
780 if (policy & PTIMER_POLICY_CONTINUOUS_TRIGGER) {
781 g_strlcat(policy_name, "continuous_trigger,", 256);
782 }
783
516deb42
DO
784 if (policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER) {
785 g_strlcat(policy_name, "no_immediate_trigger,", 256);
786 }
787
56700e1a
DO
788 if (policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD) {
789 g_strlcat(policy_name, "no_immediate_reload,", 256);
790 }
791
057516fe
DO
792 if (policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN) {
793 g_strlcat(policy_name, "no_counter_rounddown,", 256);
794 }
795
086ede32
PM
796 if (policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) {
797 g_strlcat(policy_name, "trigger_only_on_decrement,", 256);
798 }
799
072bdb07
MAL
800 g_test_add_data_func_full(
801 tmp = g_strdup_printf("/ptimer/set_count policy=%s", policy_name),
802 g_memdup(&policy, 1), check_set_count, g_free);
803 g_free(tmp);
804
805 g_test_add_data_func_full(
806 tmp = g_strdup_printf("/ptimer/set_limit policy=%s", policy_name),
807 g_memdup(&policy, 1), check_set_limit, g_free);
808 g_free(tmp);
809
810 g_test_add_data_func_full(
811 tmp = g_strdup_printf("/ptimer/oneshot policy=%s", policy_name),
812 g_memdup(&policy, 1), check_oneshot, g_free);
813 g_free(tmp);
814
815 g_test_add_data_func_full(
816 tmp = g_strdup_printf("/ptimer/periodic policy=%s", policy_name),
817 g_memdup(&policy, 1), check_periodic, g_free);
818 g_free(tmp);
819
820 g_test_add_data_func_full(
821 tmp = g_strdup_printf("/ptimer/on_the_fly_mode_change policy=%s",
822 policy_name),
823 g_memdup(&policy, 1), check_on_the_fly_mode_change, g_free);
824 g_free(tmp);
825
826 g_test_add_data_func_full(
827 tmp = g_strdup_printf("/ptimer/on_the_fly_period_change policy=%s",
828 policy_name),
829 g_memdup(&policy, 1), check_on_the_fly_period_change, g_free);
830 g_free(tmp);
831
832 g_test_add_data_func_full(
833 tmp = g_strdup_printf("/ptimer/on_the_fly_freq_change policy=%s",
834 policy_name),
835 g_memdup(&policy, 1), check_on_the_fly_freq_change, g_free);
836 g_free(tmp);
837
838 g_test_add_data_func_full(
839 tmp = g_strdup_printf("/ptimer/run_with_period_0 policy=%s",
840 policy_name),
841 g_memdup(&policy, 1), check_run_with_period_0, g_free);
842 g_free(tmp);
843
844 g_test_add_data_func_full(
845 tmp = g_strdup_printf("/ptimer/run_with_delta_0 policy=%s",
846 policy_name),
847 g_memdup(&policy, 1), check_run_with_delta_0, g_free);
848 g_free(tmp);
849
850 g_test_add_data_func_full(
851 tmp = g_strdup_printf("/ptimer/periodic_with_load_0 policy=%s",
852 policy_name),
853 g_memdup(&policy, 1), check_periodic_with_load_0, g_free);
854 g_free(tmp);
855
856 g_test_add_data_func_full(
857 tmp = g_strdup_printf("/ptimer/oneshot_with_load_0 policy=%s",
858 policy_name),
859 g_memdup(&policy, 1), check_oneshot_with_load_0, g_free);
860 g_free(tmp);
5b262bb6
DO
861}
862
293130aa
DO
863static void add_all_ptimer_policies_comb_tests(void)
864{
086ede32 865 int last_policy = PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT;
293130aa
DO
866 int policy = PTIMER_POLICY_DEFAULT;
867
868 for (; policy < (last_policy << 1); policy++) {
086ede32
PM
869 if ((policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) &&
870 (policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER)) {
871 /* Incompatible policy flag settings -- don't try to test them */
872 continue;
873 }
293130aa
DO
874 add_ptimer_tests(policy);
875 }
876}
877
5b262bb6
DO
878int main(int argc, char **argv)
879{
880 int i;
881
882 g_test_init(&argc, &argv, NULL);
883
884 for (i = 0; i < QEMU_CLOCK_MAX; i++) {
885 main_loop_tlg.tl[i] = g_new0(QEMUTimerList, 1);
886 }
887
293130aa 888 add_all_ptimer_policies_comb_tests();
5b262bb6
DO
889
890 qtest_allowed = true;
891
892 return g_test_run();
893}