Statistics
| Branch: | Revision:

root / qemu-timer.c @ 7fc7e584

History | View | Annotate | Download (20.9 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 "net.h"
27
#include "monitor.h"
28
#include "console.h"
29

    
30
#include "hw/hw.h"
31

    
32
#include <unistd.h>
33
#include <fcntl.h>
34
#include <time.h>
35
#include <errno.h>
36
#include <sys/time.h>
37
#include <signal.h>
38
#ifdef __FreeBSD__
39
#include <sys/param.h>
40
#endif
41

    
42
#ifdef _WIN32
43
#include <windows.h>
44
#include <mmsystem.h>
45
#endif
46

    
47
#include "qemu-timer.h"
48

    
49
/***********************************************************/
50
/* timers */
51

    
52
#define QEMU_CLOCK_REALTIME 0
53
#define QEMU_CLOCK_VIRTUAL  1
54
#define QEMU_CLOCK_HOST     2
55

    
56
struct QEMUClock {
57
    int type;
58
    int enabled;
59

    
60
    QEMUTimer *active_timers;
61

    
62
    NotifierList reset_notifiers;
63
    int64_t last;
64
};
65

    
66
struct QEMUTimer {
67
    QEMUClock *clock;
68
    int64_t expire_time;        /* in nanoseconds */
69
    int scale;
70
    QEMUTimerCB *cb;
71
    void *opaque;
72
    struct QEMUTimer *next;
73
};
74

    
75
struct qemu_alarm_timer {
76
    char const *name;
77
    int (*start)(struct qemu_alarm_timer *t);
78
    void (*stop)(struct qemu_alarm_timer *t);
79
    void (*rearm)(struct qemu_alarm_timer *t, int64_t nearest_delta_ns);
80
#if defined(__linux__)
81
    int fd;
82
    timer_t timer;
83
#elif defined(_WIN32)
84
    HANDLE timer;
85
#endif
86
    char expired;
87
    char pending;
88
};
89

    
90
static struct qemu_alarm_timer *alarm_timer;
91

    
92
static bool qemu_timer_expired_ns(QEMUTimer *timer_head, int64_t current_time)
93
{
94
    return timer_head && (timer_head->expire_time <= current_time);
95
}
96

    
97
int qemu_alarm_pending(void)
98
{
99
    return alarm_timer->pending;
100
}
101

    
102
static inline int alarm_has_dynticks(struct qemu_alarm_timer *t)
103
{
104
    return !!t->rearm;
105
}
106

    
107
static int64_t qemu_next_alarm_deadline(void)
108
{
109
    int64_t delta;
110
    int64_t rtdelta;
111

    
112
    if (!use_icount && vm_clock->active_timers) {
113
        delta = vm_clock->active_timers->expire_time -
114
                     qemu_get_clock_ns(vm_clock);
115
    } else {
116
        delta = INT32_MAX;
117
    }
118
    if (host_clock->active_timers) {
119
        int64_t hdelta = host_clock->active_timers->expire_time -
120
                 qemu_get_clock_ns(host_clock);
121
        if (hdelta < delta) {
122
            delta = hdelta;
123
        }
124
    }
125
    if (rt_clock->active_timers) {
126
        rtdelta = (rt_clock->active_timers->expire_time -
127
                 qemu_get_clock_ns(rt_clock));
128
        if (rtdelta < delta) {
129
            delta = rtdelta;
130
        }
131
    }
132

    
133
    return delta;
134
}
135

    
136
static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
137
{
138
    int64_t nearest_delta_ns;
139
    assert(alarm_has_dynticks(t));
140
    if (!rt_clock->active_timers &&
141
        !vm_clock->active_timers &&
142
        !host_clock->active_timers) {
143
        return;
144
    }
145
    nearest_delta_ns = qemu_next_alarm_deadline();
146
    t->rearm(t, nearest_delta_ns);
147
}
148

    
149
/* TODO: MIN_TIMER_REARM_NS should be optimized */
150
#define MIN_TIMER_REARM_NS 250000
151

    
152
#ifdef _WIN32
153

    
154
static int mm_start_timer(struct qemu_alarm_timer *t);
155
static void mm_stop_timer(struct qemu_alarm_timer *t);
156
static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
157

    
158
static int win32_start_timer(struct qemu_alarm_timer *t);
159
static void win32_stop_timer(struct qemu_alarm_timer *t);
160
static void win32_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
161

    
162
#else
163

    
164
static int unix_start_timer(struct qemu_alarm_timer *t);
165
static void unix_stop_timer(struct qemu_alarm_timer *t);
166
static void unix_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
167

    
168
#ifdef __linux__
169

    
170
static int dynticks_start_timer(struct qemu_alarm_timer *t);
171
static void dynticks_stop_timer(struct qemu_alarm_timer *t);
172
static void dynticks_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
173

    
174
#endif /* __linux__ */
175

    
176
#endif /* _WIN32 */
177

    
178
static struct qemu_alarm_timer alarm_timers[] = {
179
#ifndef _WIN32
180
#ifdef __linux__
181
    {"dynticks", dynticks_start_timer,
182
     dynticks_stop_timer, dynticks_rearm_timer},
183
#endif
184
    {"unix", unix_start_timer, unix_stop_timer, unix_rearm_timer},
185
#else
186
    {"mmtimer", mm_start_timer, mm_stop_timer, NULL},
187
    {"mmtimer2", mm_start_timer, mm_stop_timer, mm_rearm_timer},
188
    {"dynticks", win32_start_timer, win32_stop_timer, win32_rearm_timer},
189
    {"win32", win32_start_timer, win32_stop_timer, NULL},
190
#endif
191
    {NULL, }
192
};
193

    
194
static void show_available_alarms(void)
195
{
196
    int i;
197

    
198
    printf("Available alarm timers, in order of precedence:\n");
199
    for (i = 0; alarm_timers[i].name; i++)
200
        printf("%s\n", alarm_timers[i].name);
201
}
202

    
203
void configure_alarms(char const *opt)
204
{
205
    int i;
206
    int cur = 0;
207
    int count = ARRAY_SIZE(alarm_timers) - 1;
208
    char *arg;
209
    char *name;
210
    struct qemu_alarm_timer tmp;
211

    
212
    if (!strcmp(opt, "?")) {
213
        show_available_alarms();
214
        exit(0);
215
    }
216

    
217
    arg = g_strdup(opt);
218

    
219
    /* Reorder the array */
220
    name = strtok(arg, ",");
221
    while (name) {
222
        for (i = 0; i < count && alarm_timers[i].name; i++) {
223
            if (!strcmp(alarm_timers[i].name, name))
224
                break;
225
        }
226

    
227
        if (i == count) {
228
            fprintf(stderr, "Unknown clock %s\n", name);
229
            goto next;
230
        }
231

    
232
        if (i < cur)
233
            /* Ignore */
234
            goto next;
235

    
236
        /* Swap */
237
        tmp = alarm_timers[i];
238
        alarm_timers[i] = alarm_timers[cur];
239
        alarm_timers[cur] = tmp;
240

    
241
        cur++;
242
next:
243
        name = strtok(NULL, ",");
244
    }
245

    
246
    g_free(arg);
247

    
248
    if (cur) {
249
        /* Disable remaining timers */
250
        for (i = cur; i < count; i++)
251
            alarm_timers[i].name = NULL;
252
    } else {
253
        show_available_alarms();
254
        exit(1);
255
    }
256
}
257

    
258
QEMUClock *rt_clock;
259
QEMUClock *vm_clock;
260
QEMUClock *host_clock;
261

    
262
static QEMUClock *qemu_new_clock(int type)
263
{
264
    QEMUClock *clock;
265

    
266
    clock = g_malloc0(sizeof(QEMUClock));
267
    clock->type = type;
268
    clock->enabled = 1;
269
    clock->last = INT64_MIN;
270
    notifier_list_init(&clock->reset_notifiers);
271
    return clock;
272
}
273

    
274
void qemu_clock_enable(QEMUClock *clock, int enabled)
275
{
276
    bool old = clock->enabled;
277
    clock->enabled = enabled;
278
    if (enabled && !old) {
279
        qemu_rearm_alarm_timer(alarm_timer);
280
    }
281
}
282

    
283
int64_t qemu_clock_has_timers(QEMUClock *clock)
284
{
285
    return !!clock->active_timers;
286
}
287

    
288
int64_t qemu_clock_expired(QEMUClock *clock)
289
{
290
    return (clock->active_timers &&
291
            clock->active_timers->expire_time < qemu_get_clock_ns(clock));
292
}
293

    
294
int64_t qemu_clock_deadline(QEMUClock *clock)
295
{
296
    /* To avoid problems with overflow limit this to 2^32.  */
297
    int64_t delta = INT32_MAX;
298

    
299
    if (clock->active_timers) {
300
        delta = clock->active_timers->expire_time - qemu_get_clock_ns(clock);
301
    }
302
    if (delta < 0) {
303
        delta = 0;
304
    }
305
    return delta;
306
}
307

    
308
QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
309
                          QEMUTimerCB *cb, void *opaque)
310
{
311
    QEMUTimer *ts;
312

    
313
    ts = g_malloc0(sizeof(QEMUTimer));
314
    ts->clock = clock;
315
    ts->cb = cb;
316
    ts->opaque = opaque;
317
    ts->scale = scale;
318
    return ts;
319
}
320

    
321
void qemu_free_timer(QEMUTimer *ts)
322
{
323
    g_free(ts);
324
}
325

    
326
/* stop a timer, but do not dealloc it */
327
void qemu_del_timer(QEMUTimer *ts)
328
{
329
    QEMUTimer **pt, *t;
330

    
331
    /* NOTE: this code must be signal safe because
332
       qemu_timer_expired() can be called from a signal. */
333
    pt = &ts->clock->active_timers;
334
    for(;;) {
335
        t = *pt;
336
        if (!t)
337
            break;
338
        if (t == ts) {
339
            *pt = t->next;
340
            break;
341
        }
342
        pt = &t->next;
343
    }
344
}
345

    
346
/* modify the current timer so that it will be fired when current_time
347
   >= expire_time. The corresponding callback will be called. */
348
void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)
349
{
350
    QEMUTimer **pt, *t;
351

    
352
    qemu_del_timer(ts);
353

    
354
    /* add the timer in the sorted list */
355
    /* NOTE: this code must be signal safe because
356
       qemu_timer_expired() can be called from a signal. */
357
    pt = &ts->clock->active_timers;
358
    for(;;) {
359
        t = *pt;
360
        if (!qemu_timer_expired_ns(t, expire_time)) {
361
            break;
362
        }
363
        pt = &t->next;
364
    }
365
    ts->expire_time = expire_time;
366
    ts->next = *pt;
367
    *pt = ts;
368

    
369
    /* Rearm if necessary  */
370
    if (pt == &ts->clock->active_timers) {
371
        if (!alarm_timer->pending) {
372
            qemu_rearm_alarm_timer(alarm_timer);
373
        }
374
        /* Interrupt execution to force deadline recalculation.  */
375
        qemu_clock_warp(ts->clock);
376
        if (use_icount) {
377
            qemu_notify_event();
378
        }
379
    }
380
}
381

    
382
void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
383
{
384
    qemu_mod_timer_ns(ts, expire_time * ts->scale);
385
}
386

    
387
int qemu_timer_pending(QEMUTimer *ts)
388
{
389
    QEMUTimer *t;
390
    for (t = ts->clock->active_timers; t != NULL; t = t->next) {
391
        if (t == ts)
392
            return 1;
393
    }
394
    return 0;
395
}
396

    
397
int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
398
{
399
    return qemu_timer_expired_ns(timer_head, current_time * timer_head->scale);
400
}
401

    
402
static void qemu_run_timers(QEMUClock *clock)
403
{
404
    QEMUTimer **ptimer_head, *ts;
405
    int64_t current_time;
406
   
407
    if (!clock->enabled)
408
        return;
409

    
410
    current_time = qemu_get_clock_ns(clock);
411
    ptimer_head = &clock->active_timers;
412
    for(;;) {
413
        ts = *ptimer_head;
414
        if (!qemu_timer_expired_ns(ts, current_time)) {
415
            break;
416
        }
417
        /* remove timer from the list before calling the callback */
418
        *ptimer_head = ts->next;
419
        ts->next = NULL;
420

    
421
        /* run the callback (the timer list can be modified) */
422
        ts->cb(ts->opaque);
423
    }
424
}
425

    
426
int64_t qemu_get_clock_ns(QEMUClock *clock)
427
{
428
    int64_t now, last;
429

    
430
    switch(clock->type) {
431
    case QEMU_CLOCK_REALTIME:
432
        return get_clock();
433
    default:
434
    case QEMU_CLOCK_VIRTUAL:
435
        if (use_icount) {
436
            return cpu_get_icount();
437
        } else {
438
            return cpu_get_clock();
439
        }
440
    case QEMU_CLOCK_HOST:
441
        now = get_clock_realtime();
442
        last = clock->last;
443
        clock->last = now;
444
        if (now < last) {
445
            notifier_list_notify(&clock->reset_notifiers, &now);
446
        }
447
        return now;
448
    }
449
}
450

    
451
void qemu_register_clock_reset_notifier(QEMUClock *clock, Notifier *notifier)
452
{
453
    notifier_list_add(&clock->reset_notifiers, notifier);
454
}
455

    
456
void qemu_unregister_clock_reset_notifier(QEMUClock *clock, Notifier *notifier)
457
{
458
    notifier_list_remove(&clock->reset_notifiers, notifier);
459
}
460

    
461
void init_clocks(void)
462
{
463
    rt_clock = qemu_new_clock(QEMU_CLOCK_REALTIME);
464
    vm_clock = qemu_new_clock(QEMU_CLOCK_VIRTUAL);
465
    host_clock = qemu_new_clock(QEMU_CLOCK_HOST);
466
}
467

    
468
uint64_t qemu_timer_expire_time_ns(QEMUTimer *ts)
469
{
470
    return qemu_timer_pending(ts) ? ts->expire_time : -1;
471
}
472

    
473
void qemu_run_all_timers(void)
474
{
475
    alarm_timer->pending = 0;
476

    
477
    /* rearm timer, if not periodic */
478
    if (alarm_timer->expired) {
479
        alarm_timer->expired = 0;
480
        qemu_rearm_alarm_timer(alarm_timer);
481
    }
482

    
483
    /* vm time timers */
484
    qemu_run_timers(vm_clock);
485
    qemu_run_timers(rt_clock);
486
    qemu_run_timers(host_clock);
487
}
488

    
489
#ifdef _WIN32
490
static void CALLBACK host_alarm_handler(PVOID lpParam, BOOLEAN unused)
491
#else
492
static void host_alarm_handler(int host_signum)
493
#endif
494
{
495
    struct qemu_alarm_timer *t = alarm_timer;
496
    if (!t)
497
        return;
498

    
499
#if 0
500
#define DISP_FREQ 1000
501
    {
502
        static int64_t delta_min = INT64_MAX;
503
        static int64_t delta_max, delta_cum, last_clock, delta, ti;
504
        static int count;
505
        ti = qemu_get_clock_ns(vm_clock);
506
        if (last_clock != 0) {
507
            delta = ti - last_clock;
508
            if (delta < delta_min)
509
                delta_min = delta;
510
            if (delta > delta_max)
511
                delta_max = delta;
512
            delta_cum += delta;
513
            if (++count == DISP_FREQ) {
514
                printf("timer: min=%" PRId64 " us max=%" PRId64 " us avg=%" PRId64 " us avg_freq=%0.3f Hz\n",
515
                       muldiv64(delta_min, 1000000, get_ticks_per_sec()),
516
                       muldiv64(delta_max, 1000000, get_ticks_per_sec()),
517
                       muldiv64(delta_cum, 1000000 / DISP_FREQ, get_ticks_per_sec()),
518
                       (double)get_ticks_per_sec() / ((double)delta_cum / DISP_FREQ));
519
                count = 0;
520
                delta_min = INT64_MAX;
521
                delta_max = 0;
522
                delta_cum = 0;
523
            }
524
        }
525
        last_clock = ti;
526
    }
527
#endif
528
    if (alarm_has_dynticks(t) ||
529
        qemu_next_alarm_deadline () <= 0) {
530
        t->expired = alarm_has_dynticks(t);
531
        t->pending = 1;
532
        qemu_notify_event();
533
    }
534
}
535

    
536
#if defined(__linux__)
537

    
538
#include "compatfd.h"
539

    
540
static int dynticks_start_timer(struct qemu_alarm_timer *t)
541
{
542
    struct sigevent ev;
543
    timer_t host_timer;
544
    struct sigaction act;
545

    
546
    sigfillset(&act.sa_mask);
547
    act.sa_flags = 0;
548
    act.sa_handler = host_alarm_handler;
549

    
550
    sigaction(SIGALRM, &act, NULL);
551

    
552
    /* 
553
     * Initialize ev struct to 0 to avoid valgrind complaining
554
     * about uninitialized data in timer_create call
555
     */
556
    memset(&ev, 0, sizeof(ev));
557
    ev.sigev_value.sival_int = 0;
558
    ev.sigev_notify = SIGEV_SIGNAL;
559
#ifdef SIGEV_THREAD_ID
560
    if (qemu_signalfd_available()) {
561
        ev.sigev_notify = SIGEV_THREAD_ID;
562
        ev._sigev_un._tid = qemu_get_thread_id();
563
    }
564
#endif /* SIGEV_THREAD_ID */
565
    ev.sigev_signo = SIGALRM;
566

    
567
    if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) {
568
        perror("timer_create");
569

    
570
        /* disable dynticks */
571
        fprintf(stderr, "Dynamic Ticks disabled\n");
572

    
573
        return -1;
574
    }
575

    
576
    t->timer = host_timer;
577

    
578
    return 0;
579
}
580

    
581
static void dynticks_stop_timer(struct qemu_alarm_timer *t)
582
{
583
    timer_t host_timer = t->timer;
584

    
585
    timer_delete(host_timer);
586
}
587

    
588
static void dynticks_rearm_timer(struct qemu_alarm_timer *t,
589
                                 int64_t nearest_delta_ns)
590
{
591
    timer_t host_timer = t->timer;
592
    struct itimerspec timeout;
593
    int64_t current_ns;
594

    
595
    if (nearest_delta_ns < MIN_TIMER_REARM_NS)
596
        nearest_delta_ns = MIN_TIMER_REARM_NS;
597

    
598
    /* check whether a timer is already running */
599
    if (timer_gettime(host_timer, &timeout)) {
600
        perror("gettime");
601
        fprintf(stderr, "Internal timer error: aborting\n");
602
        exit(1);
603
    }
604
    current_ns = timeout.it_value.tv_sec * 1000000000LL + timeout.it_value.tv_nsec;
605
    if (current_ns && current_ns <= nearest_delta_ns)
606
        return;
607

    
608
    timeout.it_interval.tv_sec = 0;
609
    timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */
610
    timeout.it_value.tv_sec =  nearest_delta_ns / 1000000000;
611
    timeout.it_value.tv_nsec = nearest_delta_ns % 1000000000;
612
    if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {
613
        perror("settime");
614
        fprintf(stderr, "Internal timer error: aborting\n");
615
        exit(1);
616
    }
617
}
618

    
619
#endif /* defined(__linux__) */
620

    
621
#if !defined(_WIN32)
622

    
623
static int unix_start_timer(struct qemu_alarm_timer *t)
624
{
625
    struct sigaction act;
626

    
627
    /* timer signal */
628
    sigfillset(&act.sa_mask);
629
    act.sa_flags = 0;
630
    act.sa_handler = host_alarm_handler;
631

    
632
    sigaction(SIGALRM, &act, NULL);
633
    return 0;
634
}
635

    
636
static void unix_rearm_timer(struct qemu_alarm_timer *t,
637
                             int64_t nearest_delta_ns)
638
{
639
    struct itimerval itv;
640
    int err;
641

    
642
    if (nearest_delta_ns < MIN_TIMER_REARM_NS)
643
        nearest_delta_ns = MIN_TIMER_REARM_NS;
644

    
645
    itv.it_interval.tv_sec = 0;
646
    itv.it_interval.tv_usec = 0; /* 0 for one-shot timer */
647
    itv.it_value.tv_sec =  nearest_delta_ns / 1000000000;
648
    itv.it_value.tv_usec = (nearest_delta_ns % 1000000000) / 1000;
649
    err = setitimer(ITIMER_REAL, &itv, NULL);
650
    if (err) {
651
        perror("setitimer");
652
        fprintf(stderr, "Internal timer error: aborting\n");
653
        exit(1);
654
    }
655
}
656

    
657
static void unix_stop_timer(struct qemu_alarm_timer *t)
658
{
659
    struct itimerval itv;
660

    
661
    memset(&itv, 0, sizeof(itv));
662
    setitimer(ITIMER_REAL, &itv, NULL);
663
}
664

    
665
#endif /* !defined(_WIN32) */
666

    
667

    
668
#ifdef _WIN32
669

    
670
static MMRESULT mm_timer;
671
static unsigned mm_period;
672

    
673
static void CALLBACK mm_alarm_handler(UINT uTimerID, UINT uMsg,
674
                                      DWORD_PTR dwUser, DWORD_PTR dw1,
675
                                      DWORD_PTR dw2)
676
{
677
    struct qemu_alarm_timer *t = alarm_timer;
678
    if (!t) {
679
        return;
680
    }
681
    if (alarm_has_dynticks(t) || qemu_next_alarm_deadline() <= 0) {
682
        t->expired = alarm_has_dynticks(t);
683
        t->pending = 1;
684
        qemu_notify_event();
685
    }
686
}
687

    
688
static int mm_start_timer(struct qemu_alarm_timer *t)
689
{
690
    TIMECAPS tc;
691
    UINT flags;
692

    
693
    memset(&tc, 0, sizeof(tc));
694
    timeGetDevCaps(&tc, sizeof(tc));
695

    
696
    mm_period = tc.wPeriodMin;
697
    timeBeginPeriod(mm_period);
698

    
699
    flags = TIME_CALLBACK_FUNCTION;
700
    if (alarm_has_dynticks(t)) {
701
        flags |= TIME_ONESHOT;
702
    } else {
703
        flags |= TIME_PERIODIC;
704
    }
705

    
706
    mm_timer = timeSetEvent(1,                  /* interval (ms) */
707
                            mm_period,          /* resolution */
708
                            mm_alarm_handler,   /* function */
709
                            (DWORD_PTR)t,       /* parameter */
710
                            flags);
711

    
712
    if (!mm_timer) {
713
        fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
714
                GetLastError());
715
        timeEndPeriod(mm_period);
716
        return -1;
717
    }
718

    
719
    return 0;
720
}
721

    
722
static void mm_stop_timer(struct qemu_alarm_timer *t)
723
{
724
    timeKillEvent(mm_timer);
725
    timeEndPeriod(mm_period);
726
}
727

    
728
static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta)
729
{
730
    int nearest_delta_ms = (delta + 999999) / 1000000;
731
    if (nearest_delta_ms < 1) {
732
        nearest_delta_ms = 1;
733
    }
734

    
735
    timeKillEvent(mm_timer);
736
    mm_timer = timeSetEvent(nearest_delta_ms,
737
                            mm_period,
738
                            mm_alarm_handler,
739
                            (DWORD_PTR)t,
740
                            TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
741

    
742
    if (!mm_timer) {
743
        fprintf(stderr, "Failed to re-arm win32 alarm timer %ld\n",
744
                GetLastError());
745

    
746
        timeEndPeriod(mm_period);
747
        exit(1);
748
    }
749
}
750

    
751
static int win32_start_timer(struct qemu_alarm_timer *t)
752
{
753
    HANDLE hTimer;
754
    BOOLEAN success;
755

    
756
    /* If you call ChangeTimerQueueTimer on a one-shot timer (its period
757
       is zero) that has already expired, the timer is not updated.  Since
758
       creating a new timer is relatively expensive, set a bogus one-hour
759
       interval in the dynticks case.  */
760
    success = CreateTimerQueueTimer(&hTimer,
761
                          NULL,
762
                          host_alarm_handler,
763
                          t,
764
                          1,
765
                          alarm_has_dynticks(t) ? 3600000 : 1,
766
                          WT_EXECUTEINTIMERTHREAD);
767

    
768
    if (!success) {
769
        fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
770
                GetLastError());
771
        return -1;
772
    }
773

    
774
    t->timer = hTimer;
775
    return 0;
776
}
777

    
778
static void win32_stop_timer(struct qemu_alarm_timer *t)
779
{
780
    HANDLE hTimer = t->timer;
781

    
782
    if (hTimer) {
783
        DeleteTimerQueueTimer(NULL, hTimer, NULL);
784
    }
785
}
786

    
787
static void win32_rearm_timer(struct qemu_alarm_timer *t,
788
                              int64_t nearest_delta_ns)
789
{
790
    HANDLE hTimer = t->timer;
791
    int nearest_delta_ms;
792
    BOOLEAN success;
793

    
794
    nearest_delta_ms = (nearest_delta_ns + 999999) / 1000000;
795
    if (nearest_delta_ms < 1) {
796
        nearest_delta_ms = 1;
797
    }
798
    success = ChangeTimerQueueTimer(NULL,
799
                                    hTimer,
800
                                    nearest_delta_ms,
801
                                    3600000);
802

    
803
    if (!success) {
804
        fprintf(stderr, "Failed to rearm win32 alarm timer: %ld\n",
805
                GetLastError());
806
        exit(-1);
807
    }
808

    
809
}
810

    
811
#endif /* _WIN32 */
812

    
813
static void quit_timers(void)
814
{
815
    struct qemu_alarm_timer *t = alarm_timer;
816
    alarm_timer = NULL;
817
    t->stop(t);
818
}
819

    
820
int init_timer_alarm(void)
821
{
822
    struct qemu_alarm_timer *t = NULL;
823
    int i, err = -1;
824

    
825
    for (i = 0; alarm_timers[i].name; i++) {
826
        t = &alarm_timers[i];
827

    
828
        err = t->start(t);
829
        if (!err)
830
            break;
831
    }
832

    
833
    if (err) {
834
        err = -ENOENT;
835
        goto fail;
836
    }
837

    
838
    /* first event is at time 0 */
839
    atexit(quit_timers);
840
    t->pending = 1;
841
    alarm_timer = t;
842

    
843
    return 0;
844

    
845
fail:
846
    return err;
847
}
848

    
849
int qemu_calculate_timeout(void)
850
{
851
    return 1000;
852
}
853