]> Git Repo - qemu.git/blob - tests/ptimer-test.c
Merge remote-tracking branch 'remotes/famz/tags/various-pull-request' into staging
[qemu.git] / tests / ptimer-test.c
1 /*
2  * QTest testcase for the ptimer
3  *
4  * Author: Dmitry Osipenko <[email protected]>
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
20 static bool triggered;
21
22 static void ptimer_trigger(void *opaque)
23 {
24     triggered = true;
25 }
26
27 static 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
46 static void ptimer_test_set_qemu_time_ns(int64_t ns)
47 {
48     ptimer_test_time_ns = ns;
49 }
50
51 static 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
65 static void check_set_count(gconstpointer arg)
66 {
67     const uint8_t *policy = arg;
68     QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
69     ptimer_state *ptimer = ptimer_init(bh, *policy);
70
71     triggered = false;
72
73     ptimer_set_count(ptimer, 1000);
74     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 1000);
75     g_assert_false(triggered);
76 }
77
78 static void check_set_limit(gconstpointer arg)
79 {
80     const uint8_t *policy = arg;
81     QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
82     ptimer_state *ptimer = ptimer_init(bh, *policy);
83
84     triggered = false;
85
86     ptimer_set_limit(ptimer, 1000, 0);
87     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
88     g_assert_cmpuint(ptimer_get_limit(ptimer), ==, 1000);
89     g_assert_false(triggered);
90
91     ptimer_set_limit(ptimer, 2000, 1);
92     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 2000);
93     g_assert_cmpuint(ptimer_get_limit(ptimer), ==, 2000);
94     g_assert_false(triggered);
95 }
96
97 static void check_oneshot(gconstpointer arg)
98 {
99     const uint8_t *policy = arg;
100     QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
101     ptimer_state *ptimer = ptimer_init(bh, *policy);
102
103     triggered = false;
104
105     ptimer_set_period(ptimer, 2000000);
106     ptimer_set_count(ptimer, 10);
107     ptimer_run(ptimer, 1);
108
109     qemu_clock_step(2000000 * 2 + 100000);
110
111     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 7);
112     g_assert_false(triggered);
113
114     ptimer_stop(ptimer);
115
116     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 7);
117     g_assert_false(triggered);
118
119     qemu_clock_step(2000000 * 11);
120
121     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 7);
122     g_assert_false(triggered);
123
124     ptimer_run(ptimer, 1);
125
126     qemu_clock_step(2000000 * 7 + 100000);
127
128     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
129     g_assert_true(triggered);
130
131     triggered = false;
132
133     qemu_clock_step(2000000);
134
135     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
136     g_assert_false(triggered);
137
138     qemu_clock_step(4000000);
139
140     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
141     g_assert_false(triggered);
142
143     ptimer_set_count(ptimer, 10);
144
145     qemu_clock_step(20000000 + 100000);
146
147     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
148     g_assert_false(triggered);
149
150     ptimer_set_limit(ptimer, 9, 1);
151
152     qemu_clock_step(20000000 + 100000);
153
154     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 9);
155     g_assert_false(triggered);
156
157     ptimer_run(ptimer, 1);
158
159     qemu_clock_step(2000000 + 100000);
160
161     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 7);
162     g_assert_false(triggered);
163
164     ptimer_set_count(ptimer, 20);
165
166     qemu_clock_step(2000000 * 19 + 100000);
167
168     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
169     g_assert_false(triggered);
170
171     qemu_clock_step(2000000);
172
173     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
174     g_assert_true(triggered);
175
176     ptimer_stop(ptimer);
177
178     triggered = false;
179
180     qemu_clock_step(2000000 * 12 + 100000);
181
182     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
183     g_assert_false(triggered);
184 }
185
186 static void check_periodic(gconstpointer arg)
187 {
188     const uint8_t *policy = arg;
189     QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
190     ptimer_state *ptimer = ptimer_init(bh, *policy);
191
192     triggered = false;
193
194     ptimer_set_period(ptimer, 2000000);
195     ptimer_set_limit(ptimer, 10, 1);
196     ptimer_run(ptimer, 0);
197
198     qemu_clock_step(2000000 * 10 + 100000);
199
200     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 9);
201     g_assert_true(triggered);
202
203     triggered = false;
204
205     qemu_clock_step(2000000);
206
207     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 8);
208     g_assert_false(triggered);
209
210     ptimer_set_count(ptimer, 20);
211
212     qemu_clock_step(2000000 * 11 + 100000);
213
214     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 8);
215     g_assert_false(triggered);
216
217     qemu_clock_step(2000000 * 10);
218
219     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 8);
220     g_assert_true(triggered);
221
222     ptimer_stop(ptimer);
223     triggered = false;
224
225     qemu_clock_step(2000000);
226
227     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 8);
228     g_assert_false(triggered);
229
230     ptimer_set_count(ptimer, 3);
231     ptimer_run(ptimer, 0);
232
233     qemu_clock_step(2000000 * 3 + 100000);
234
235     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 9);
236     g_assert_true(triggered);
237
238     triggered = false;
239
240     qemu_clock_step(2000000);
241
242     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 8);
243     g_assert_false(triggered);
244
245     ptimer_set_count(ptimer, 0);
246     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
247     g_assert_true(triggered);
248
249     triggered = false;
250
251     qemu_clock_step(2000000 * 12 + 100000);
252
253     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 7);
254     g_assert_true(triggered);
255
256     ptimer_stop(ptimer);
257
258     triggered = false;
259
260     qemu_clock_step(2000000 * 12 + 100000);
261
262     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 7);
263     g_assert_false(triggered);
264
265     ptimer_run(ptimer, 0);
266     ptimer_set_period(ptimer, 0);
267
268     qemu_clock_step(2000000 + 100000);
269
270     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 7);
271     g_assert_false(triggered);
272 }
273
274 static void check_on_the_fly_mode_change(gconstpointer arg)
275 {
276     const uint8_t *policy = arg;
277     QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
278     ptimer_state *ptimer = ptimer_init(bh, *policy);
279
280     triggered = false;
281
282     ptimer_set_period(ptimer, 2000000);
283     ptimer_set_limit(ptimer, 10, 1);
284     ptimer_run(ptimer, 1);
285
286     qemu_clock_step(2000000 * 9 + 100000);
287
288     ptimer_run(ptimer, 0);
289
290     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
291     g_assert_false(triggered);
292
293     qemu_clock_step(2000000);
294
295     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 9);
296     g_assert_true(triggered);
297
298     triggered = false;
299
300     qemu_clock_step(2000000 * 9);
301
302     ptimer_run(ptimer, 1);
303
304     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
305     g_assert_false(triggered);
306
307     qemu_clock_step(2000000 * 3);
308
309     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
310     g_assert_true(triggered);
311 }
312
313 static void check_on_the_fly_period_change(gconstpointer arg)
314 {
315     const uint8_t *policy = arg;
316     QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
317     ptimer_state *ptimer = ptimer_init(bh, *policy);
318
319     triggered = false;
320
321     ptimer_set_period(ptimer, 2000000);
322     ptimer_set_limit(ptimer, 8, 1);
323     ptimer_run(ptimer, 1);
324
325     qemu_clock_step(2000000 * 4 + 100000);
326
327     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 3);
328     g_assert_false(triggered);
329
330     ptimer_set_period(ptimer, 4000000);
331     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 3);
332
333     qemu_clock_step(4000000 * 2 + 100000);
334
335     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
336     g_assert_false(triggered);
337
338     qemu_clock_step(4000000 * 2);
339
340     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
341     g_assert_true(triggered);
342 }
343
344 static void check_on_the_fly_freq_change(gconstpointer arg)
345 {
346     const uint8_t *policy = arg;
347     QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
348     ptimer_state *ptimer = ptimer_init(bh, *policy);
349
350     triggered = false;
351
352     ptimer_set_freq(ptimer, 500);
353     ptimer_set_limit(ptimer, 8, 1);
354     ptimer_run(ptimer, 1);
355
356     qemu_clock_step(2000000 * 4 + 100000);
357
358     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 3);
359     g_assert_false(triggered);
360
361     ptimer_set_freq(ptimer, 250);
362     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 3);
363
364     qemu_clock_step(2000000 * 4 + 100000);
365
366     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
367     g_assert_false(triggered);
368
369     qemu_clock_step(2000000 * 4);
370
371     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
372     g_assert_true(triggered);
373 }
374
375 static void check_run_with_period_0(gconstpointer arg)
376 {
377     const uint8_t *policy = arg;
378     QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
379     ptimer_state *ptimer = ptimer_init(bh, *policy);
380
381     triggered = false;
382
383     ptimer_set_count(ptimer, 99);
384     ptimer_run(ptimer, 1);
385
386     qemu_clock_step(10 * NANOSECONDS_PER_SECOND);
387
388     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 99);
389     g_assert_false(triggered);
390 }
391
392 static void check_run_with_delta_0(gconstpointer arg)
393 {
394     const uint8_t *policy = arg;
395     QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
396     ptimer_state *ptimer = ptimer_init(bh, *policy);
397
398     triggered = false;
399
400     ptimer_set_period(ptimer, 2000000);
401     ptimer_set_limit(ptimer, 99, 0);
402     ptimer_run(ptimer, 1);
403     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 99);
404     g_assert_true(triggered);
405
406     triggered = false;
407
408     qemu_clock_step(2000000 + 100000);
409
410     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 97);
411     g_assert_false(triggered);
412
413     qemu_clock_step(2000000 * 97);
414
415     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
416     g_assert_false(triggered);
417
418     qemu_clock_step(2000000 * 2);
419
420     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
421     g_assert_true(triggered);
422
423     triggered = false;
424
425     ptimer_set_count(ptimer, 0);
426     ptimer_run(ptimer, 0);
427     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 99);
428     g_assert_true(triggered);
429
430     triggered = false;
431
432     qemu_clock_step(2000000 + 100000);
433
434     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 97);
435     g_assert_false(triggered);
436
437     qemu_clock_step(2000000 * 98);
438
439     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 98);
440     g_assert_true(triggered);
441
442     ptimer_stop(ptimer);
443 }
444
445 static void check_periodic_with_load_0(gconstpointer arg)
446 {
447     const uint8_t *policy = arg;
448     QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
449     ptimer_state *ptimer = ptimer_init(bh, *policy);
450
451     triggered = false;
452
453     ptimer_set_period(ptimer, 2000000);
454     ptimer_run(ptimer, 0);
455
456     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
457     g_assert_true(triggered);
458
459     triggered = false;
460
461     qemu_clock_step(2000000 + 100000);
462
463     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
464     g_assert_false(triggered);
465
466     ptimer_stop(ptimer);
467 }
468
469 static void check_oneshot_with_load_0(gconstpointer arg)
470 {
471     const uint8_t *policy = arg;
472     QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
473     ptimer_state *ptimer = ptimer_init(bh, *policy);
474
475     triggered = false;
476
477     ptimer_set_period(ptimer, 2000000);
478     ptimer_run(ptimer, 1);
479
480     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
481     g_assert_true(triggered);
482
483     triggered = false;
484
485     qemu_clock_step(2000000 + 100000);
486
487     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
488     g_assert_false(triggered);
489
490     triggered = false;
491
492     qemu_clock_step(2000000 + 100000);
493
494     g_assert_false(triggered);
495 }
496
497 static void add_ptimer_tests(uint8_t policy)
498 {
499     uint8_t *ppolicy = g_malloc(1);
500     char *policy_name = g_malloc(64);
501
502     *ppolicy = policy;
503
504     if (policy == PTIMER_POLICY_DEFAULT) {
505         g_sprintf(policy_name, "default");
506     }
507
508     qtest_add_data_func(
509         g_strdup_printf("/ptimer/set_count policy=%s", policy_name),
510         ppolicy, check_set_count);
511
512     qtest_add_data_func(
513         g_strdup_printf("/ptimer/set_limit policy=%s", policy_name),
514         ppolicy, check_set_limit);
515
516     qtest_add_data_func(
517         g_strdup_printf("/ptimer/oneshot policy=%s", policy_name),
518         ppolicy, check_oneshot);
519
520     qtest_add_data_func(
521         g_strdup_printf("/ptimer/periodic policy=%s", policy_name),
522         ppolicy, check_periodic);
523
524     qtest_add_data_func(
525         g_strdup_printf("/ptimer/on_the_fly_mode_change policy=%s", policy_name),
526         ppolicy, check_on_the_fly_mode_change);
527
528     qtest_add_data_func(
529         g_strdup_printf("/ptimer/on_the_fly_period_change policy=%s", policy_name),
530         ppolicy, check_on_the_fly_period_change);
531
532     qtest_add_data_func(
533         g_strdup_printf("/ptimer/on_the_fly_freq_change policy=%s", policy_name),
534         ppolicy, check_on_the_fly_freq_change);
535
536     qtest_add_data_func(
537         g_strdup_printf("/ptimer/run_with_period_0 policy=%s", policy_name),
538         ppolicy, check_run_with_period_0);
539
540     qtest_add_data_func(
541         g_strdup_printf("/ptimer/run_with_delta_0 policy=%s", policy_name),
542         ppolicy, check_run_with_delta_0);
543
544     qtest_add_data_func(
545         g_strdup_printf("/ptimer/periodic_with_load_0 policy=%s", policy_name),
546         ppolicy, check_periodic_with_load_0);
547
548     qtest_add_data_func(
549         g_strdup_printf("/ptimer/oneshot_with_load_0 policy=%s", policy_name),
550         ppolicy, check_oneshot_with_load_0);
551 }
552
553 int main(int argc, char **argv)
554 {
555     int i;
556
557     g_test_init(&argc, &argv, NULL);
558
559     for (i = 0; i < QEMU_CLOCK_MAX; i++) {
560         main_loop_tlg.tl[i] = g_new0(QEMUTimerList, 1);
561     }
562
563     add_ptimer_tests(PTIMER_POLICY_DEFAULT);
564
565     qtest_allowed = true;
566
567     return g_test_run();
568 }
This page took 0.052367 seconds and 4 git commands to generate.