]> git.proxmox.com Git - qemu.git/blob - qemu-timer.c
aio / timers: Add QEMUTimerListGroup and helper functions
[qemu.git] / qemu-timer.c
1 /*
2 * QEMU System Emulator
3 *
4 * Copyright (c) 2003-2008 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25 #include "sysemu/sysemu.h"
26 #include "monitor/monitor.h"
27 #include "ui/console.h"
28
29 #include "hw/hw.h"
30
31 #include "qemu/timer.h"
32 #ifdef CONFIG_POSIX
33 #include <pthread.h>
34 #endif
35
36 #ifdef _WIN32
37 #include <mmsystem.h>
38 #endif
39
40 #ifdef CONFIG_PPOLL
41 #include <poll.h>
42 #endif
43
44 #ifdef CONFIG_PRCTL_PR_SET_TIMERSLACK
45 #include <sys/prctl.h>
46 #endif
47
48 /***********************************************************/
49 /* timers */
50
51 struct QEMUClock {
52 QEMUTimerList *main_loop_timerlist;
53 QLIST_HEAD(, QEMUTimerList) timerlists;
54
55 NotifierList reset_notifiers;
56 int64_t last;
57
58 QEMUClockType type;
59 bool enabled;
60 };
61
62 QEMUTimerListGroup main_loop_tlg;
63 QEMUClock *qemu_clocks[QEMU_CLOCK_MAX];
64
65 /* A QEMUTimerList is a list of timers attached to a clock. More
66 * than one QEMUTimerList can be attached to each clock, for instance
67 * used by different AioContexts / threads. Each clock also has
68 * a list of the QEMUTimerLists associated with it, in order that
69 * reenabling the clock can call all the notifiers.
70 */
71
72 struct QEMUTimerList {
73 QEMUClock *clock;
74 QEMUTimer *active_timers;
75 QLIST_ENTRY(QEMUTimerList) list;
76 };
77
78 struct qemu_alarm_timer {
79 char const *name;
80 int (*start)(struct qemu_alarm_timer *t);
81 void (*stop)(struct qemu_alarm_timer *t);
82 void (*rearm)(struct qemu_alarm_timer *t, int64_t nearest_delta_ns);
83 #if defined(__linux__)
84 timer_t timer;
85 int fd;
86 #elif defined(_WIN32)
87 HANDLE timer;
88 #endif
89 bool expired;
90 bool pending;
91 };
92
93 static struct qemu_alarm_timer *alarm_timer;
94
95 static bool timer_expired_ns(QEMUTimer *timer_head, int64_t current_time)
96 {
97 return timer_head && (timer_head->expire_time <= current_time);
98 }
99
100 static int64_t qemu_next_alarm_deadline(void)
101 {
102 int64_t delta = INT64_MAX;
103 int64_t rtdelta;
104 int64_t hdelta;
105
106 if (!use_icount && vm_clock->enabled &&
107 vm_clock->main_loop_timerlist->active_timers) {
108 delta = vm_clock->main_loop_timerlist->active_timers->expire_time -
109 qemu_get_clock_ns(vm_clock);
110 }
111 if (host_clock->enabled &&
112 host_clock->main_loop_timerlist->active_timers) {
113 hdelta = host_clock->main_loop_timerlist->active_timers->expire_time -
114 qemu_get_clock_ns(host_clock);
115 if (hdelta < delta) {
116 delta = hdelta;
117 }
118 }
119 if (rt_clock->enabled &&
120 rt_clock->main_loop_timerlist->active_timers) {
121 rtdelta = (rt_clock->main_loop_timerlist->active_timers->expire_time -
122 qemu_get_clock_ns(rt_clock));
123 if (rtdelta < delta) {
124 delta = rtdelta;
125 }
126 }
127
128 return delta;
129 }
130
131 static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
132 {
133 int64_t nearest_delta_ns = qemu_next_alarm_deadline();
134 if (nearest_delta_ns < INT64_MAX) {
135 t->rearm(t, nearest_delta_ns);
136 }
137 }
138
139 /* TODO: MIN_TIMER_REARM_NS should be optimized */
140 #define MIN_TIMER_REARM_NS 250000
141
142 #ifdef _WIN32
143
144 static int mm_start_timer(struct qemu_alarm_timer *t);
145 static void mm_stop_timer(struct qemu_alarm_timer *t);
146 static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
147
148 static int win32_start_timer(struct qemu_alarm_timer *t);
149 static void win32_stop_timer(struct qemu_alarm_timer *t);
150 static void win32_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
151
152 #else
153
154 static int unix_start_timer(struct qemu_alarm_timer *t);
155 static void unix_stop_timer(struct qemu_alarm_timer *t);
156 static void unix_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
157
158 #ifdef __linux__
159
160 static int dynticks_start_timer(struct qemu_alarm_timer *t);
161 static void dynticks_stop_timer(struct qemu_alarm_timer *t);
162 static void dynticks_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
163
164 #endif /* __linux__ */
165
166 #endif /* _WIN32 */
167
168 static struct qemu_alarm_timer alarm_timers[] = {
169 #ifndef _WIN32
170 #ifdef __linux__
171 {"dynticks", dynticks_start_timer,
172 dynticks_stop_timer, dynticks_rearm_timer},
173 #endif
174 {"unix", unix_start_timer, unix_stop_timer, unix_rearm_timer},
175 #else
176 {"mmtimer", mm_start_timer, mm_stop_timer, mm_rearm_timer},
177 {"dynticks", win32_start_timer, win32_stop_timer, win32_rearm_timer},
178 #endif
179 {NULL, }
180 };
181
182 static void show_available_alarms(void)
183 {
184 int i;
185
186 printf("Available alarm timers, in order of precedence:\n");
187 for (i = 0; alarm_timers[i].name; i++)
188 printf("%s\n", alarm_timers[i].name);
189 }
190
191 void configure_alarms(char const *opt)
192 {
193 int i;
194 int cur = 0;
195 int count = ARRAY_SIZE(alarm_timers) - 1;
196 char *arg;
197 char *name;
198 struct qemu_alarm_timer tmp;
199
200 if (is_help_option(opt)) {
201 show_available_alarms();
202 exit(0);
203 }
204
205 arg = g_strdup(opt);
206
207 /* Reorder the array */
208 name = strtok(arg, ",");
209 while (name) {
210 for (i = 0; i < count && alarm_timers[i].name; i++) {
211 if (!strcmp(alarm_timers[i].name, name))
212 break;
213 }
214
215 if (i == count) {
216 fprintf(stderr, "Unknown clock %s\n", name);
217 goto next;
218 }
219
220 if (i < cur)
221 /* Ignore */
222 goto next;
223
224 /* Swap */
225 tmp = alarm_timers[i];
226 alarm_timers[i] = alarm_timers[cur];
227 alarm_timers[cur] = tmp;
228
229 cur++;
230 next:
231 name = strtok(NULL, ",");
232 }
233
234 g_free(arg);
235
236 if (cur) {
237 /* Disable remaining timers */
238 for (i = cur; i < count; i++)
239 alarm_timers[i].name = NULL;
240 } else {
241 show_available_alarms();
242 exit(1);
243 }
244 }
245
246 static QEMUTimerList *timerlist_new_from_clock(QEMUClock *clock)
247 {
248 QEMUTimerList *timer_list;
249
250 /* Assert if we do not have a clock. If you see this
251 * assertion in means that the clocks have not been
252 * initialised before a timerlist is needed. This
253 * normally happens if an AioContext is used before
254 * init_clocks() is called within main().
255 */
256 assert(clock);
257
258 timer_list = g_malloc0(sizeof(QEMUTimerList));
259 timer_list->clock = clock;
260 QLIST_INSERT_HEAD(&clock->timerlists, timer_list, list);
261 return timer_list;
262 }
263
264 QEMUTimerList *timerlist_new(QEMUClockType type)
265 {
266 return timerlist_new_from_clock(qemu_clock_ptr(type));
267 }
268
269 void timerlist_free(QEMUTimerList *timer_list)
270 {
271 assert(!timerlist_has_timers(timer_list));
272 if (timer_list->clock) {
273 QLIST_REMOVE(timer_list, list);
274 if (timer_list->clock->main_loop_timerlist == timer_list) {
275 timer_list->clock->main_loop_timerlist = NULL;
276 }
277 }
278 g_free(timer_list);
279 }
280
281 static QEMUClock *qemu_clock_new(QEMUClockType type)
282 {
283 QEMUClock *clock;
284
285 clock = g_malloc0(sizeof(QEMUClock));
286 clock->type = type;
287 clock->enabled = true;
288 clock->last = INT64_MIN;
289 QLIST_INIT(&clock->timerlists);
290 notifier_list_init(&clock->reset_notifiers);
291 clock->main_loop_timerlist = timerlist_new_from_clock(clock);
292 return clock;
293 }
294
295 bool qemu_clock_use_for_deadline(QEMUClock *clock)
296 {
297 return !(use_icount && (clock->type == QEMU_CLOCK_VIRTUAL));
298 }
299
300 void qemu_clock_enable(QEMUClock *clock, bool enabled)
301 {
302 bool old = clock->enabled;
303 clock->enabled = enabled;
304 if (enabled && !old) {
305 qemu_rearm_alarm_timer(alarm_timer);
306 }
307 }
308
309 bool timerlist_has_timers(QEMUTimerList *timer_list)
310 {
311 return !!timer_list->active_timers;
312 }
313
314 bool qemu_clock_has_timers(QEMUClock *clock)
315 {
316 return timerlist_has_timers(clock->main_loop_timerlist);
317 }
318
319 bool timerlist_expired(QEMUTimerList *timer_list)
320 {
321 return (timer_list->active_timers &&
322 timer_list->active_timers->expire_time <
323 qemu_get_clock_ns(timer_list->clock));
324 }
325
326 bool qemu_clock_expired(QEMUClock *clock)
327 {
328 return timerlist_expired(clock->main_loop_timerlist);
329 }
330
331 int64_t timerlist_deadline(QEMUTimerList *timer_list)
332 {
333 /* To avoid problems with overflow limit this to 2^32. */
334 int64_t delta = INT32_MAX;
335
336 if (timer_list->clock->enabled && timer_list->active_timers) {
337 delta = timer_list->active_timers->expire_time -
338 qemu_get_clock_ns(timer_list->clock);
339 }
340 if (delta < 0) {
341 delta = 0;
342 }
343 return delta;
344 }
345
346 int64_t qemu_clock_deadline(QEMUClock *clock)
347 {
348 return timerlist_deadline(clock->main_loop_timerlist);
349 }
350
351 /*
352 * As above, but return -1 for no deadline, and do not cap to 2^32
353 * as we know the result is always positive.
354 */
355
356 int64_t timerlist_deadline_ns(QEMUTimerList *timer_list)
357 {
358 int64_t delta;
359
360 if (!timer_list->clock->enabled || !timer_list->active_timers) {
361 return -1;
362 }
363
364 delta = timer_list->active_timers->expire_time -
365 qemu_get_clock_ns(timer_list->clock);
366
367 if (delta <= 0) {
368 return 0;
369 }
370
371 return delta;
372 }
373
374 int64_t qemu_clock_deadline_ns(QEMUClock *clock)
375 {
376 return timerlist_deadline_ns(clock->main_loop_timerlist);
377 }
378
379 QEMUClock *timerlist_get_clock(QEMUTimerList *timer_list)
380 {
381 return timer_list->clock;
382 }
383
384 QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClock *clock)
385 {
386 return clock->main_loop_timerlist;
387 }
388
389 /* Transition function to convert a nanosecond timeout to ms
390 * This is used where a system does not support ppoll
391 */
392 int qemu_timeout_ns_to_ms(int64_t ns)
393 {
394 int64_t ms;
395 if (ns < 0) {
396 return -1;
397 }
398
399 if (!ns) {
400 return 0;
401 }
402
403 /* Always round up, because it's better to wait too long than to wait too
404 * little and effectively busy-wait
405 */
406 ms = (ns + SCALE_MS - 1) / SCALE_MS;
407
408 /* To avoid overflow problems, limit this to 2^31, i.e. approx 25 days */
409 if (ms > (int64_t) INT32_MAX) {
410 ms = INT32_MAX;
411 }
412
413 return (int) ms;
414 }
415
416
417 /* qemu implementation of g_poll which uses a nanosecond timeout but is
418 * otherwise identical to g_poll
419 */
420 int qemu_poll_ns(GPollFD *fds, guint nfds, int64_t timeout)
421 {
422 #ifdef CONFIG_PPOLL
423 if (timeout < 0) {
424 return ppoll((struct pollfd *)fds, nfds, NULL, NULL);
425 } else {
426 struct timespec ts;
427 ts.tv_sec = timeout / 1000000000LL;
428 ts.tv_nsec = timeout % 1000000000LL;
429 return ppoll((struct pollfd *)fds, nfds, &ts, NULL);
430 }
431 #else
432 return g_poll(fds, nfds, qemu_timeout_ns_to_ms(timeout));
433 #endif
434 }
435
436
437 void timer_init(QEMUTimer *ts,
438 QEMUTimerList *timer_list, int scale,
439 QEMUTimerCB *cb, void *opaque)
440 {
441 ts->timer_list = timer_list;
442 ts->cb = cb;
443 ts->opaque = opaque;
444 ts->scale = scale;
445 }
446
447 QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
448 QEMUTimerCB *cb, void *opaque)
449 {
450 return timer_new_tl(clock->main_loop_timerlist,
451 scale, cb, opaque);
452 }
453
454 void qemu_free_timer(QEMUTimer *ts)
455 {
456 g_free(ts);
457 }
458
459 /* stop a timer, but do not dealloc it */
460 void qemu_del_timer(QEMUTimer *ts)
461 {
462 QEMUTimer **pt, *t;
463
464 /* NOTE: this code must be signal safe because
465 timer_expired() can be called from a signal. */
466 pt = &ts->timer_list->active_timers;
467 for(;;) {
468 t = *pt;
469 if (!t)
470 break;
471 if (t == ts) {
472 *pt = t->next;
473 break;
474 }
475 pt = &t->next;
476 }
477 }
478
479 /* modify the current timer so that it will be fired when current_time
480 >= expire_time. The corresponding callback will be called. */
481 void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)
482 {
483 QEMUTimer **pt, *t;
484
485 qemu_del_timer(ts);
486
487 /* add the timer in the sorted list */
488 /* NOTE: this code must be signal safe because
489 timer_expired() can be called from a signal. */
490 pt = &ts->timer_list->active_timers;
491 for(;;) {
492 t = *pt;
493 if (!timer_expired_ns(t, expire_time)) {
494 break;
495 }
496 pt = &t->next;
497 }
498 ts->expire_time = expire_time;
499 ts->next = *pt;
500 *pt = ts;
501
502 /* Rearm if necessary */
503 if (pt == &ts->timer_list->active_timers) {
504 if (!alarm_timer->pending) {
505 qemu_rearm_alarm_timer(alarm_timer);
506 }
507 /* Interrupt execution to force deadline recalculation. */
508 qemu_clock_warp(ts->timer_list->clock);
509 if (use_icount) {
510 qemu_notify_event();
511 }
512 }
513 }
514
515 void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
516 {
517 qemu_mod_timer_ns(ts, expire_time * ts->scale);
518 }
519
520 bool timer_pending(QEMUTimer *ts)
521 {
522 QEMUTimer *t;
523 for (t = ts->timer_list->active_timers; t != NULL; t = t->next) {
524 if (t == ts) {
525 return true;
526 }
527 }
528 return false;
529 }
530
531 bool timer_expired(QEMUTimer *timer_head, int64_t current_time)
532 {
533 return timer_expired_ns(timer_head, current_time * timer_head->scale);
534 }
535
536 bool timerlist_run_timers(QEMUTimerList *timer_list)
537 {
538 QEMUTimer *ts;
539 int64_t current_time;
540 bool progress = false;
541
542 if (!timer_list->clock->enabled) {
543 return progress;
544 }
545
546 current_time = qemu_get_clock_ns(timer_list->clock);
547 for(;;) {
548 ts = timer_list->active_timers;
549 if (!timer_expired_ns(ts, current_time)) {
550 break;
551 }
552 /* remove timer from the list before calling the callback */
553 timer_list->active_timers = ts->next;
554 ts->next = NULL;
555
556 /* run the callback (the timer list can be modified) */
557 ts->cb(ts->opaque);
558 progress = true;
559 }
560 return progress;
561 }
562
563 bool qemu_run_timers(QEMUClock *clock)
564 {
565 return timerlist_run_timers(clock->main_loop_timerlist);
566 }
567
568 void timerlistgroup_init(QEMUTimerListGroup *tlg)
569 {
570 QEMUClockType type;
571 for (type = 0; type < QEMU_CLOCK_MAX; type++) {
572 tlg->tl[type] = timerlist_new(type);
573 }
574 }
575
576 void timerlistgroup_deinit(QEMUTimerListGroup *tlg)
577 {
578 QEMUClockType type;
579 for (type = 0; type < QEMU_CLOCK_MAX; type++) {
580 timerlist_free(tlg->tl[type]);
581 }
582 }
583
584 bool timerlistgroup_run_timers(QEMUTimerListGroup *tlg)
585 {
586 QEMUClockType type;
587 bool progress = false;
588 for (type = 0; type < QEMU_CLOCK_MAX; type++) {
589 progress |= timerlist_run_timers(tlg->tl[type]);
590 }
591 return progress;
592 }
593
594 int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg)
595 {
596 int64_t deadline = -1;
597 QEMUClockType type;
598 for (type = 0; type < QEMU_CLOCK_MAX; type++) {
599 if (qemu_clock_use_for_deadline(tlg->tl[type]->clock)) {
600 deadline = qemu_soonest_timeout(deadline,
601 timerlist_deadline_ns(
602 tlg->tl[type]));
603 }
604 }
605 return deadline;
606 }
607
608 int64_t qemu_get_clock_ns(QEMUClock *clock)
609 {
610 int64_t now, last;
611
612 switch(clock->type) {
613 case QEMU_CLOCK_REALTIME:
614 return get_clock();
615 default:
616 case QEMU_CLOCK_VIRTUAL:
617 if (use_icount) {
618 return cpu_get_icount();
619 } else {
620 return cpu_get_clock();
621 }
622 case QEMU_CLOCK_HOST:
623 now = get_clock_realtime();
624 last = clock->last;
625 clock->last = now;
626 if (now < last) {
627 notifier_list_notify(&clock->reset_notifiers, &now);
628 }
629 return now;
630 }
631 }
632
633 void qemu_register_clock_reset_notifier(QEMUClock *clock, Notifier *notifier)
634 {
635 notifier_list_add(&clock->reset_notifiers, notifier);
636 }
637
638 void qemu_unregister_clock_reset_notifier(QEMUClock *clock, Notifier *notifier)
639 {
640 notifier_remove(notifier);
641 }
642
643 void init_clocks(void)
644 {
645 QEMUClockType type;
646 for (type = 0; type < QEMU_CLOCK_MAX; type++) {
647 if (!qemu_clocks[type]) {
648 qemu_clocks[type] = qemu_clock_new(type);
649 main_loop_tlg.tl[type] = qemu_clocks[type]->main_loop_timerlist;
650 }
651 }
652
653 #ifdef CONFIG_PRCTL_PR_SET_TIMERSLACK
654 prctl(PR_SET_TIMERSLACK, 1, 0, 0, 0);
655 #endif
656 }
657
658 uint64_t timer_expire_time_ns(QEMUTimer *ts)
659 {
660 return timer_pending(ts) ? ts->expire_time : -1;
661 }
662
663 bool qemu_run_all_timers(void)
664 {
665 bool progress = false;
666 alarm_timer->pending = false;
667
668 /* vm time timers */
669 QEMUClockType type;
670 for (type = 0; type < QEMU_CLOCK_MAX; type++) {
671 progress |= qemu_run_timers(qemu_clock_ptr(type));
672 }
673
674 /* rearm timer, if not periodic */
675 if (alarm_timer->expired) {
676 alarm_timer->expired = false;
677 qemu_rearm_alarm_timer(alarm_timer);
678 }
679
680 return progress;
681 }
682
683 #ifdef _WIN32
684 static void CALLBACK host_alarm_handler(PVOID lpParam, BOOLEAN unused)
685 #else
686 static void host_alarm_handler(int host_signum)
687 #endif
688 {
689 struct qemu_alarm_timer *t = alarm_timer;
690 if (!t)
691 return;
692
693 t->expired = true;
694 t->pending = true;
695 qemu_notify_event();
696 }
697
698 #if defined(__linux__)
699
700 #include "qemu/compatfd.h"
701
702 static int dynticks_start_timer(struct qemu_alarm_timer *t)
703 {
704 struct sigevent ev;
705 timer_t host_timer;
706 struct sigaction act;
707
708 sigfillset(&act.sa_mask);
709 act.sa_flags = 0;
710 act.sa_handler = host_alarm_handler;
711
712 sigaction(SIGALRM, &act, NULL);
713
714 /*
715 * Initialize ev struct to 0 to avoid valgrind complaining
716 * about uninitialized data in timer_create call
717 */
718 memset(&ev, 0, sizeof(ev));
719 ev.sigev_value.sival_int = 0;
720 ev.sigev_notify = SIGEV_SIGNAL;
721 #ifdef CONFIG_SIGEV_THREAD_ID
722 if (qemu_signalfd_available()) {
723 ev.sigev_notify = SIGEV_THREAD_ID;
724 ev._sigev_un._tid = qemu_get_thread_id();
725 }
726 #endif /* CONFIG_SIGEV_THREAD_ID */
727 ev.sigev_signo = SIGALRM;
728
729 if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) {
730 perror("timer_create");
731 return -1;
732 }
733
734 t->timer = host_timer;
735
736 return 0;
737 }
738
739 static void dynticks_stop_timer(struct qemu_alarm_timer *t)
740 {
741 timer_t host_timer = t->timer;
742
743 timer_delete(host_timer);
744 }
745
746 static void dynticks_rearm_timer(struct qemu_alarm_timer *t,
747 int64_t nearest_delta_ns)
748 {
749 timer_t host_timer = t->timer;
750 struct itimerspec timeout;
751 int64_t current_ns;
752
753 if (nearest_delta_ns < MIN_TIMER_REARM_NS)
754 nearest_delta_ns = MIN_TIMER_REARM_NS;
755
756 /* check whether a timer is already running */
757 if (timer_gettime(host_timer, &timeout)) {
758 perror("gettime");
759 fprintf(stderr, "Internal timer error: aborting\n");
760 exit(1);
761 }
762 current_ns = timeout.it_value.tv_sec * 1000000000LL + timeout.it_value.tv_nsec;
763 if (current_ns && current_ns <= nearest_delta_ns)
764 return;
765
766 timeout.it_interval.tv_sec = 0;
767 timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */
768 timeout.it_value.tv_sec = nearest_delta_ns / 1000000000;
769 timeout.it_value.tv_nsec = nearest_delta_ns % 1000000000;
770 if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {
771 perror("settime");
772 fprintf(stderr, "Internal timer error: aborting\n");
773 exit(1);
774 }
775 }
776
777 #endif /* defined(__linux__) */
778
779 #if !defined(_WIN32)
780
781 static int unix_start_timer(struct qemu_alarm_timer *t)
782 {
783 struct sigaction act;
784
785 /* timer signal */
786 sigfillset(&act.sa_mask);
787 act.sa_flags = 0;
788 act.sa_handler = host_alarm_handler;
789
790 sigaction(SIGALRM, &act, NULL);
791 return 0;
792 }
793
794 static void unix_rearm_timer(struct qemu_alarm_timer *t,
795 int64_t nearest_delta_ns)
796 {
797 struct itimerval itv;
798 int err;
799
800 if (nearest_delta_ns < MIN_TIMER_REARM_NS)
801 nearest_delta_ns = MIN_TIMER_REARM_NS;
802
803 itv.it_interval.tv_sec = 0;
804 itv.it_interval.tv_usec = 0; /* 0 for one-shot timer */
805 itv.it_value.tv_sec = nearest_delta_ns / 1000000000;
806 itv.it_value.tv_usec = (nearest_delta_ns % 1000000000) / 1000;
807 err = setitimer(ITIMER_REAL, &itv, NULL);
808 if (err) {
809 perror("setitimer");
810 fprintf(stderr, "Internal timer error: aborting\n");
811 exit(1);
812 }
813 }
814
815 static void unix_stop_timer(struct qemu_alarm_timer *t)
816 {
817 struct itimerval itv;
818
819 memset(&itv, 0, sizeof(itv));
820 setitimer(ITIMER_REAL, &itv, NULL);
821 }
822
823 #endif /* !defined(_WIN32) */
824
825
826 #ifdef _WIN32
827
828 static MMRESULT mm_timer;
829 static TIMECAPS mm_tc;
830
831 static void CALLBACK mm_alarm_handler(UINT uTimerID, UINT uMsg,
832 DWORD_PTR dwUser, DWORD_PTR dw1,
833 DWORD_PTR dw2)
834 {
835 struct qemu_alarm_timer *t = alarm_timer;
836 if (!t) {
837 return;
838 }
839 t->expired = true;
840 t->pending = true;
841 qemu_notify_event();
842 }
843
844 static int mm_start_timer(struct qemu_alarm_timer *t)
845 {
846 timeGetDevCaps(&mm_tc, sizeof(mm_tc));
847 return 0;
848 }
849
850 static void mm_stop_timer(struct qemu_alarm_timer *t)
851 {
852 if (mm_timer) {
853 timeKillEvent(mm_timer);
854 }
855 }
856
857 static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta)
858 {
859 int64_t nearest_delta_ms = delta / 1000000;
860 if (nearest_delta_ms < mm_tc.wPeriodMin) {
861 nearest_delta_ms = mm_tc.wPeriodMin;
862 } else if (nearest_delta_ms > mm_tc.wPeriodMax) {
863 nearest_delta_ms = mm_tc.wPeriodMax;
864 }
865
866 if (mm_timer) {
867 timeKillEvent(mm_timer);
868 }
869 mm_timer = timeSetEvent((UINT)nearest_delta_ms,
870 mm_tc.wPeriodMin,
871 mm_alarm_handler,
872 (DWORD_PTR)t,
873 TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
874
875 if (!mm_timer) {
876 fprintf(stderr, "Failed to re-arm win32 alarm timer\n");
877 timeEndPeriod(mm_tc.wPeriodMin);
878 exit(1);
879 }
880 }
881
882 static int win32_start_timer(struct qemu_alarm_timer *t)
883 {
884 HANDLE hTimer;
885 BOOLEAN success;
886
887 /* If you call ChangeTimerQueueTimer on a one-shot timer (its period
888 is zero) that has already expired, the timer is not updated. Since
889 creating a new timer is relatively expensive, set a bogus one-hour
890 interval in the dynticks case. */
891 success = CreateTimerQueueTimer(&hTimer,
892 NULL,
893 host_alarm_handler,
894 t,
895 1,
896 3600000,
897 WT_EXECUTEINTIMERTHREAD);
898
899 if (!success) {
900 fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
901 GetLastError());
902 return -1;
903 }
904
905 t->timer = hTimer;
906 return 0;
907 }
908
909 static void win32_stop_timer(struct qemu_alarm_timer *t)
910 {
911 HANDLE hTimer = t->timer;
912
913 if (hTimer) {
914 DeleteTimerQueueTimer(NULL, hTimer, NULL);
915 }
916 }
917
918 static void win32_rearm_timer(struct qemu_alarm_timer *t,
919 int64_t nearest_delta_ns)
920 {
921 HANDLE hTimer = t->timer;
922 int64_t nearest_delta_ms;
923 BOOLEAN success;
924
925 nearest_delta_ms = nearest_delta_ns / 1000000;
926 if (nearest_delta_ms < 1) {
927 nearest_delta_ms = 1;
928 }
929 /* ULONG_MAX can be 32 bit */
930 if (nearest_delta_ms > ULONG_MAX) {
931 nearest_delta_ms = ULONG_MAX;
932 }
933 success = ChangeTimerQueueTimer(NULL,
934 hTimer,
935 (unsigned long) nearest_delta_ms,
936 3600000);
937
938 if (!success) {
939 fprintf(stderr, "Failed to rearm win32 alarm timer: %ld\n",
940 GetLastError());
941 exit(-1);
942 }
943
944 }
945
946 #endif /* _WIN32 */
947
948 static void quit_timers(void)
949 {
950 struct qemu_alarm_timer *t = alarm_timer;
951 alarm_timer = NULL;
952 t->stop(t);
953 }
954
955 #ifdef CONFIG_POSIX
956 static void reinit_timers(void)
957 {
958 struct qemu_alarm_timer *t = alarm_timer;
959 t->stop(t);
960 if (t->start(t)) {
961 fprintf(stderr, "Internal timer error: aborting\n");
962 exit(1);
963 }
964 qemu_rearm_alarm_timer(t);
965 }
966 #endif /* CONFIG_POSIX */
967
968 int init_timer_alarm(void)
969 {
970 struct qemu_alarm_timer *t = NULL;
971 int i, err = -1;
972
973 if (alarm_timer) {
974 return 0;
975 }
976
977 for (i = 0; alarm_timers[i].name; i++) {
978 t = &alarm_timers[i];
979
980 err = t->start(t);
981 if (!err)
982 break;
983 }
984
985 if (err) {
986 err = -ENOENT;
987 goto fail;
988 }
989
990 atexit(quit_timers);
991 #ifdef CONFIG_POSIX
992 pthread_atfork(NULL, NULL, reinit_timers);
993 #endif
994 alarm_timer = t;
995 return 0;
996
997 fail:
998 return err;
999 }
1000