Statistics
| Branch: | Revision:

root / qemu-timer.c @ 1de7afc9

History | View | Annotate | Download (19.2 kB)

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.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
/***********************************************************/
41
/* timers */
42

    
43
#define QEMU_CLOCK_REALTIME 0
44
#define QEMU_CLOCK_VIRTUAL  1
45
#define QEMU_CLOCK_HOST     2
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 qemu_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_new_clock(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->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
QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
281
                          QEMUTimerCB *cb, void *opaque)
282
{
283
    QEMUTimer *ts;
284

    
285
    ts = g_malloc0(sizeof(QEMUTimer));
286
    ts->clock = clock;
287
    ts->cb = cb;
288
    ts->opaque = opaque;
289
    ts->scale = scale;
290
    return ts;
291
}
292

    
293
void qemu_free_timer(QEMUTimer *ts)
294
{
295
    g_free(ts);
296
}
297

    
298
/* stop a timer, but do not dealloc it */
299
void qemu_del_timer(QEMUTimer *ts)
300
{
301
    QEMUTimer **pt, *t;
302

    
303
    /* NOTE: this code must be signal safe because
304
       qemu_timer_expired() can be called from a signal. */
305
    pt = &ts->clock->active_timers;
306
    for(;;) {
307
        t = *pt;
308
        if (!t)
309
            break;
310
        if (t == ts) {
311
            *pt = t->next;
312
            break;
313
        }
314
        pt = &t->next;
315
    }
316
}
317

    
318
/* modify the current timer so that it will be fired when current_time
319
   >= expire_time. The corresponding callback will be called. */
320
void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)
321
{
322
    QEMUTimer **pt, *t;
323

    
324
    qemu_del_timer(ts);
325

    
326
    /* add the timer in the sorted list */
327
    /* NOTE: this code must be signal safe because
328
       qemu_timer_expired() can be called from a signal. */
329
    pt = &ts->clock->active_timers;
330
    for(;;) {
331
        t = *pt;
332
        if (!qemu_timer_expired_ns(t, expire_time)) {
333
            break;
334
        }
335
        pt = &t->next;
336
    }
337
    ts->expire_time = expire_time;
338
    ts->next = *pt;
339
    *pt = ts;
340

    
341
    /* Rearm if necessary  */
342
    if (pt == &ts->clock->active_timers) {
343
        if (!alarm_timer->pending) {
344
            qemu_rearm_alarm_timer(alarm_timer);
345
        }
346
        /* Interrupt execution to force deadline recalculation.  */
347
        qemu_clock_warp(ts->clock);
348
        if (use_icount) {
349
            qemu_notify_event();
350
        }
351
    }
352
}
353

    
354
void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
355
{
356
    qemu_mod_timer_ns(ts, expire_time * ts->scale);
357
}
358

    
359
bool qemu_timer_pending(QEMUTimer *ts)
360
{
361
    QEMUTimer *t;
362
    for (t = ts->clock->active_timers; t != NULL; t = t->next) {
363
        if (t == ts) {
364
            return true;
365
        }
366
    }
367
    return false;
368
}
369

    
370
bool qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
371
{
372
    return qemu_timer_expired_ns(timer_head, current_time * timer_head->scale);
373
}
374

    
375
void qemu_run_timers(QEMUClock *clock)
376
{
377
    QEMUTimer *ts;
378
    int64_t current_time;
379
   
380
    if (!clock->enabled)
381
        return;
382

    
383
    current_time = qemu_get_clock_ns(clock);
384
    for(;;) {
385
        ts = clock->active_timers;
386
        if (!qemu_timer_expired_ns(ts, current_time)) {
387
            break;
388
        }
389
        /* remove timer from the list before calling the callback */
390
        clock->active_timers = ts->next;
391
        ts->next = NULL;
392

    
393
        /* run the callback (the timer list can be modified) */
394
        ts->cb(ts->opaque);
395
    }
396
}
397

    
398
int64_t qemu_get_clock_ns(QEMUClock *clock)
399
{
400
    int64_t now, last;
401

    
402
    switch(clock->type) {
403
    case QEMU_CLOCK_REALTIME:
404
        return get_clock();
405
    default:
406
    case QEMU_CLOCK_VIRTUAL:
407
        if (use_icount) {
408
            return cpu_get_icount();
409
        } else {
410
            return cpu_get_clock();
411
        }
412
    case QEMU_CLOCK_HOST:
413
        now = get_clock_realtime();
414
        last = clock->last;
415
        clock->last = now;
416
        if (now < last) {
417
            notifier_list_notify(&clock->reset_notifiers, &now);
418
        }
419
        return now;
420
    }
421
}
422

    
423
void qemu_register_clock_reset_notifier(QEMUClock *clock, Notifier *notifier)
424
{
425
    notifier_list_add(&clock->reset_notifiers, notifier);
426
}
427

    
428
void qemu_unregister_clock_reset_notifier(QEMUClock *clock, Notifier *notifier)
429
{
430
    notifier_remove(notifier);
431
}
432

    
433
void init_clocks(void)
434
{
435
    if (!rt_clock) {
436
        rt_clock = qemu_new_clock(QEMU_CLOCK_REALTIME);
437
        vm_clock = qemu_new_clock(QEMU_CLOCK_VIRTUAL);
438
        host_clock = qemu_new_clock(QEMU_CLOCK_HOST);
439
    }
440
}
441

    
442
uint64_t qemu_timer_expire_time_ns(QEMUTimer *ts)
443
{
444
    return qemu_timer_pending(ts) ? ts->expire_time : -1;
445
}
446

    
447
void qemu_run_all_timers(void)
448
{
449
    alarm_timer->pending = false;
450

    
451
    /* vm time timers */
452
    qemu_run_timers(vm_clock);
453
    qemu_run_timers(rt_clock);
454
    qemu_run_timers(host_clock);
455

    
456
    /* rearm timer, if not periodic */
457
    if (alarm_timer->expired) {
458
        alarm_timer->expired = false;
459
        qemu_rearm_alarm_timer(alarm_timer);
460
    }
461
}
462

    
463
#ifdef _WIN32
464
static void CALLBACK host_alarm_handler(PVOID lpParam, BOOLEAN unused)
465
#else
466
static void host_alarm_handler(int host_signum)
467
#endif
468
{
469
    struct qemu_alarm_timer *t = alarm_timer;
470
    if (!t)
471
        return;
472

    
473
    t->expired = true;
474
    t->pending = true;
475
    qemu_notify_event();
476
}
477

    
478
#if defined(__linux__)
479

    
480
#include "qemu/compatfd.h"
481

    
482
static int dynticks_start_timer(struct qemu_alarm_timer *t)
483
{
484
    struct sigevent ev;
485
    timer_t host_timer;
486
    struct sigaction act;
487

    
488
    sigfillset(&act.sa_mask);
489
    act.sa_flags = 0;
490
    act.sa_handler = host_alarm_handler;
491

    
492
    sigaction(SIGALRM, &act, NULL);
493

    
494
    /* 
495
     * Initialize ev struct to 0 to avoid valgrind complaining
496
     * about uninitialized data in timer_create call
497
     */
498
    memset(&ev, 0, sizeof(ev));
499
    ev.sigev_value.sival_int = 0;
500
    ev.sigev_notify = SIGEV_SIGNAL;
501
#ifdef CONFIG_SIGEV_THREAD_ID
502
    if (qemu_signalfd_available()) {
503
        ev.sigev_notify = SIGEV_THREAD_ID;
504
        ev._sigev_un._tid = qemu_get_thread_id();
505
    }
506
#endif /* CONFIG_SIGEV_THREAD_ID */
507
    ev.sigev_signo = SIGALRM;
508

    
509
    if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) {
510
        perror("timer_create");
511
        return -1;
512
    }
513

    
514
    t->timer = host_timer;
515

    
516
    return 0;
517
}
518

    
519
static void dynticks_stop_timer(struct qemu_alarm_timer *t)
520
{
521
    timer_t host_timer = t->timer;
522

    
523
    timer_delete(host_timer);
524
}
525

    
526
static void dynticks_rearm_timer(struct qemu_alarm_timer *t,
527
                                 int64_t nearest_delta_ns)
528
{
529
    timer_t host_timer = t->timer;
530
    struct itimerspec timeout;
531
    int64_t current_ns;
532

    
533
    if (nearest_delta_ns < MIN_TIMER_REARM_NS)
534
        nearest_delta_ns = MIN_TIMER_REARM_NS;
535

    
536
    /* check whether a timer is already running */
537
    if (timer_gettime(host_timer, &timeout)) {
538
        perror("gettime");
539
        fprintf(stderr, "Internal timer error: aborting\n");
540
        exit(1);
541
    }
542
    current_ns = timeout.it_value.tv_sec * 1000000000LL + timeout.it_value.tv_nsec;
543
    if (current_ns && current_ns <= nearest_delta_ns)
544
        return;
545

    
546
    timeout.it_interval.tv_sec = 0;
547
    timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */
548
    timeout.it_value.tv_sec =  nearest_delta_ns / 1000000000;
549
    timeout.it_value.tv_nsec = nearest_delta_ns % 1000000000;
550
    if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {
551
        perror("settime");
552
        fprintf(stderr, "Internal timer error: aborting\n");
553
        exit(1);
554
    }
555
}
556

    
557
#endif /* defined(__linux__) */
558

    
559
#if !defined(_WIN32)
560

    
561
static int unix_start_timer(struct qemu_alarm_timer *t)
562
{
563
    struct sigaction act;
564

    
565
    /* timer signal */
566
    sigfillset(&act.sa_mask);
567
    act.sa_flags = 0;
568
    act.sa_handler = host_alarm_handler;
569

    
570
    sigaction(SIGALRM, &act, NULL);
571
    return 0;
572
}
573

    
574
static void unix_rearm_timer(struct qemu_alarm_timer *t,
575
                             int64_t nearest_delta_ns)
576
{
577
    struct itimerval itv;
578
    int err;
579

    
580
    if (nearest_delta_ns < MIN_TIMER_REARM_NS)
581
        nearest_delta_ns = MIN_TIMER_REARM_NS;
582

    
583
    itv.it_interval.tv_sec = 0;
584
    itv.it_interval.tv_usec = 0; /* 0 for one-shot timer */
585
    itv.it_value.tv_sec =  nearest_delta_ns / 1000000000;
586
    itv.it_value.tv_usec = (nearest_delta_ns % 1000000000) / 1000;
587
    err = setitimer(ITIMER_REAL, &itv, NULL);
588
    if (err) {
589
        perror("setitimer");
590
        fprintf(stderr, "Internal timer error: aborting\n");
591
        exit(1);
592
    }
593
}
594

    
595
static void unix_stop_timer(struct qemu_alarm_timer *t)
596
{
597
    struct itimerval itv;
598

    
599
    memset(&itv, 0, sizeof(itv));
600
    setitimer(ITIMER_REAL, &itv, NULL);
601
}
602

    
603
#endif /* !defined(_WIN32) */
604

    
605

    
606
#ifdef _WIN32
607

    
608
static MMRESULT mm_timer;
609
static TIMECAPS mm_tc;
610

    
611
static void CALLBACK mm_alarm_handler(UINT uTimerID, UINT uMsg,
612
                                      DWORD_PTR dwUser, DWORD_PTR dw1,
613
                                      DWORD_PTR dw2)
614
{
615
    struct qemu_alarm_timer *t = alarm_timer;
616
    if (!t) {
617
        return;
618
    }
619
    t->expired = true;
620
    t->pending = true;
621
    qemu_notify_event();
622
}
623

    
624
static int mm_start_timer(struct qemu_alarm_timer *t)
625
{
626
    timeGetDevCaps(&mm_tc, sizeof(mm_tc));
627

    
628
    timeBeginPeriod(mm_tc.wPeriodMin);
629

    
630
    mm_timer = timeSetEvent(mm_tc.wPeriodMin,   /* interval (ms) */
631
                            mm_tc.wPeriodMin,   /* resolution */
632
                            mm_alarm_handler,   /* function */
633
                            (DWORD_PTR)t,       /* parameter */
634
                            TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
635

    
636
    if (!mm_timer) {
637
        fprintf(stderr, "Failed to initialize win32 alarm timer\n");
638
        timeEndPeriod(mm_tc.wPeriodMin);
639
        return -1;
640
    }
641

    
642
    return 0;
643
}
644

    
645
static void mm_stop_timer(struct qemu_alarm_timer *t)
646
{
647
    timeKillEvent(mm_timer);
648
    timeEndPeriod(mm_tc.wPeriodMin);
649
}
650

    
651
static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta)
652
{
653
    int64_t nearest_delta_ms = delta / 1000000;
654
    if (nearest_delta_ms < mm_tc.wPeriodMin) {
655
        nearest_delta_ms = mm_tc.wPeriodMin;
656
    } else if (nearest_delta_ms > mm_tc.wPeriodMax) {
657
        nearest_delta_ms = mm_tc.wPeriodMax;
658
    }
659

    
660
    timeKillEvent(mm_timer);
661
    mm_timer = timeSetEvent((UINT)nearest_delta_ms,
662
                            mm_tc.wPeriodMin,
663
                            mm_alarm_handler,
664
                            (DWORD_PTR)t,
665
                            TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
666

    
667
    if (!mm_timer) {
668
        fprintf(stderr, "Failed to re-arm win32 alarm timer\n");
669
        timeEndPeriod(mm_tc.wPeriodMin);
670
        exit(1);
671
    }
672
}
673

    
674
static int win32_start_timer(struct qemu_alarm_timer *t)
675
{
676
    HANDLE hTimer;
677
    BOOLEAN success;
678

    
679
    /* If you call ChangeTimerQueueTimer on a one-shot timer (its period
680
       is zero) that has already expired, the timer is not updated.  Since
681
       creating a new timer is relatively expensive, set a bogus one-hour
682
       interval in the dynticks case.  */
683
    success = CreateTimerQueueTimer(&hTimer,
684
                          NULL,
685
                          host_alarm_handler,
686
                          t,
687
                          1,
688
                          3600000,
689
                          WT_EXECUTEINTIMERTHREAD);
690

    
691
    if (!success) {
692
        fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
693
                GetLastError());
694
        return -1;
695
    }
696

    
697
    t->timer = hTimer;
698
    return 0;
699
}
700

    
701
static void win32_stop_timer(struct qemu_alarm_timer *t)
702
{
703
    HANDLE hTimer = t->timer;
704

    
705
    if (hTimer) {
706
        DeleteTimerQueueTimer(NULL, hTimer, NULL);
707
    }
708
}
709

    
710
static void win32_rearm_timer(struct qemu_alarm_timer *t,
711
                              int64_t nearest_delta_ns)
712
{
713
    HANDLE hTimer = t->timer;
714
    int64_t nearest_delta_ms;
715
    BOOLEAN success;
716

    
717
    nearest_delta_ms = nearest_delta_ns / 1000000;
718
    if (nearest_delta_ms < 1) {
719
        nearest_delta_ms = 1;
720
    }
721
    /* ULONG_MAX can be 32 bit */
722
    if (nearest_delta_ms > ULONG_MAX) {
723
        nearest_delta_ms = ULONG_MAX;
724
    }
725
    success = ChangeTimerQueueTimer(NULL,
726
                                    hTimer,
727
                                    (unsigned long) nearest_delta_ms,
728
                                    3600000);
729

    
730
    if (!success) {
731
        fprintf(stderr, "Failed to rearm win32 alarm timer: %ld\n",
732
                GetLastError());
733
        exit(-1);
734
    }
735

    
736
}
737

    
738
#endif /* _WIN32 */
739

    
740
static void quit_timers(void)
741
{
742
    struct qemu_alarm_timer *t = alarm_timer;
743
    alarm_timer = NULL;
744
    t->stop(t);
745
}
746

    
747
#ifdef CONFIG_POSIX
748
static void reinit_timers(void)
749
{
750
    struct qemu_alarm_timer *t = alarm_timer;
751
    t->stop(t);
752
    if (t->start(t)) {
753
        fprintf(stderr, "Internal timer error: aborting\n");
754
        exit(1);
755
    }
756
    qemu_rearm_alarm_timer(t);
757
}
758
#endif /* CONFIG_POSIX */
759

    
760
int init_timer_alarm(void)
761
{
762
    struct qemu_alarm_timer *t = NULL;
763
    int i, err = -1;
764

    
765
    if (alarm_timer) {
766
        return 0;
767
    }
768

    
769
    for (i = 0; alarm_timers[i].name; i++) {
770
        t = &alarm_timers[i];
771

    
772
        err = t->start(t);
773
        if (!err)
774
            break;
775
    }
776

    
777
    if (err) {
778
        err = -ENOENT;
779
        goto fail;
780
    }
781

    
782
    atexit(quit_timers);
783
#ifdef CONFIG_POSIX
784
    pthread_atfork(NULL, NULL, reinit_timers);
785
#endif
786
    alarm_timer = t;
787
    return 0;
788

    
789
fail:
790
    return err;
791
}
792