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