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