Statistics
| Branch: | Revision:

root / qemu-timer.c @ 2ff68d07

History | View | Annotate | Download (21 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
    clock->enabled = enabled;
277
}
278

    
279
int64_t qemu_clock_has_timers(QEMUClock *clock)
280
{
281
    return !!clock->active_timers;
282
}
283

    
284
int64_t qemu_clock_expired(QEMUClock *clock)
285
{
286
    return (clock->active_timers &&
287
            clock->active_timers->expire_time < qemu_get_clock_ns(clock));
288
}
289

    
290
int64_t qemu_clock_deadline(QEMUClock *clock)
291
{
292
    /* To avoid problems with overflow limit this to 2^32.  */
293
    int64_t delta = INT32_MAX;
294

    
295
    if (clock->active_timers) {
296
        delta = clock->active_timers->expire_time - qemu_get_clock_ns(clock);
297
    }
298
    if (delta < 0) {
299
        delta = 0;
300
    }
301
    return delta;
302
}
303

    
304
QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
305
                          QEMUTimerCB *cb, void *opaque)
306
{
307
    QEMUTimer *ts;
308

    
309
    ts = g_malloc0(sizeof(QEMUTimer));
310
    ts->clock = clock;
311
    ts->cb = cb;
312
    ts->opaque = opaque;
313
    ts->scale = scale;
314
    return ts;
315
}
316

    
317
void qemu_free_timer(QEMUTimer *ts)
318
{
319
    g_free(ts);
320
}
321

    
322
/* stop a timer, but do not dealloc it */
323
void qemu_del_timer(QEMUTimer *ts)
324
{
325
    QEMUTimer **pt, *t;
326

    
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 (!t)
333
            break;
334
        if (t == ts) {
335
            *pt = t->next;
336
            break;
337
        }
338
        pt = &t->next;
339
    }
340
}
341

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

    
348
    qemu_del_timer(ts);
349

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

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

    
378
void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
379
{
380
    qemu_mod_timer_ns(ts, expire_time * ts->scale);
381
}
382

    
383
int qemu_timer_pending(QEMUTimer *ts)
384
{
385
    QEMUTimer *t;
386
    for (t = ts->clock->active_timers; t != NULL; t = t->next) {
387
        if (t == ts)
388
            return 1;
389
    }
390
    return 0;
391
}
392

    
393
int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
394
{
395
    return qemu_timer_expired_ns(timer_head, current_time * timer_head->scale);
396
}
397

    
398
static void qemu_run_timers(QEMUClock *clock)
399
{
400
    QEMUTimer **ptimer_head, *ts;
401
    int64_t current_time;
402
   
403
    if (!clock->enabled)
404
        return;
405

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

    
417
        /* run the callback (the timer list can be modified) */
418
        ts->cb(ts->opaque);
419
    }
420
}
421

    
422
int64_t qemu_get_clock_ns(QEMUClock *clock)
423
{
424
    int64_t now, last;
425

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

    
447
void qemu_register_clock_reset_notifier(QEMUClock *clock, Notifier *notifier)
448
{
449
    notifier_list_add(&clock->reset_notifiers, notifier);
450
}
451

    
452
void qemu_unregister_clock_reset_notifier(QEMUClock *clock, Notifier *notifier)
453
{
454
    notifier_list_remove(&clock->reset_notifiers, notifier);
455
}
456

    
457
void init_clocks(void)
458
{
459
    rt_clock = qemu_new_clock(QEMU_CLOCK_REALTIME);
460
    vm_clock = qemu_new_clock(QEMU_CLOCK_VIRTUAL);
461
    host_clock = qemu_new_clock(QEMU_CLOCK_HOST);
462
}
463

    
464
uint64_t qemu_timer_expire_time_ns(QEMUTimer *ts)
465
{
466
    return qemu_timer_pending(ts) ? ts->expire_time : -1;
467
}
468

    
469
void qemu_run_all_timers(void)
470
{
471
    alarm_timer->pending = 0;
472

    
473
    /* rearm timer, if not periodic */
474
    if (alarm_timer->expired) {
475
        alarm_timer->expired = 0;
476
        qemu_rearm_alarm_timer(alarm_timer);
477
    }
478

    
479
    /* vm time timers */
480
    qemu_run_timers(vm_clock);
481
    qemu_run_timers(rt_clock);
482
    qemu_run_timers(host_clock);
483
}
484

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

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

    
532
#if defined(__linux__)
533

    
534
#include "compatfd.h"
535

    
536
static int dynticks_start_timer(struct qemu_alarm_timer *t)
537
{
538
    struct sigevent ev;
539
    timer_t host_timer;
540
    struct sigaction act;
541

    
542
    sigfillset(&act.sa_mask);
543
    act.sa_flags = 0;
544
    act.sa_handler = host_alarm_handler;
545

    
546
    sigaction(SIGALRM, &act, NULL);
547

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

    
563
    if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) {
564
        perror("timer_create");
565

    
566
        /* disable dynticks */
567
        fprintf(stderr, "Dynamic Ticks disabled\n");
568

    
569
        return -1;
570
    }
571

    
572
    t->timer = host_timer;
573

    
574
    return 0;
575
}
576

    
577
static void dynticks_stop_timer(struct qemu_alarm_timer *t)
578
{
579
    timer_t host_timer = t->timer;
580

    
581
    timer_delete(host_timer);
582
}
583

    
584
static void dynticks_rearm_timer(struct qemu_alarm_timer *t,
585
                                 int64_t nearest_delta_ns)
586
{
587
    timer_t host_timer = t->timer;
588
    struct itimerspec timeout;
589
    int64_t current_ns;
590

    
591
    if (nearest_delta_ns < MIN_TIMER_REARM_NS)
592
        nearest_delta_ns = MIN_TIMER_REARM_NS;
593

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

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

    
615
#endif /* defined(__linux__) */
616

    
617
#if !defined(_WIN32)
618

    
619
static int unix_start_timer(struct qemu_alarm_timer *t)
620
{
621
    struct sigaction act;
622

    
623
    /* timer signal */
624
    sigfillset(&act.sa_mask);
625
    act.sa_flags = 0;
626
    act.sa_handler = host_alarm_handler;
627

    
628
    sigaction(SIGALRM, &act, NULL);
629
    return 0;
630
}
631

    
632
static void unix_rearm_timer(struct qemu_alarm_timer *t,
633
                             int64_t nearest_delta_ns)
634
{
635
    struct itimerval itv;
636
    int err;
637

    
638
    if (nearest_delta_ns < MIN_TIMER_REARM_NS)
639
        nearest_delta_ns = MIN_TIMER_REARM_NS;
640

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

    
653
static void unix_stop_timer(struct qemu_alarm_timer *t)
654
{
655
    struct itimerval itv;
656

    
657
    memset(&itv, 0, sizeof(itv));
658
    setitimer(ITIMER_REAL, &itv, NULL);
659
}
660

    
661
#endif /* !defined(_WIN32) */
662

    
663

    
664
#ifdef _WIN32
665

    
666
static MMRESULT mm_timer;
667
static unsigned mm_period;
668

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

    
684
static int mm_start_timer(struct qemu_alarm_timer *t)
685
{
686
    TIMECAPS tc;
687
    UINT flags;
688

    
689
    memset(&tc, 0, sizeof(tc));
690
    timeGetDevCaps(&tc, sizeof(tc));
691

    
692
    mm_period = tc.wPeriodMin;
693
    timeBeginPeriod(mm_period);
694

    
695
    flags = TIME_CALLBACK_FUNCTION;
696
    if (alarm_has_dynticks(t)) {
697
        flags |= TIME_ONESHOT;
698
    } else {
699
        flags |= TIME_PERIODIC;
700
    }
701

    
702
    mm_timer = timeSetEvent(1,                  /* interval (ms) */
703
                            mm_period,          /* resolution */
704
                            mm_alarm_handler,   /* function */
705
                            (DWORD_PTR)t,       /* parameter */
706
                            flags);
707

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

    
715
    return 0;
716
}
717

    
718
static void mm_stop_timer(struct qemu_alarm_timer *t)
719
{
720
    timeKillEvent(mm_timer);
721
    timeEndPeriod(mm_period);
722
}
723

    
724
static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta)
725
{
726
    int nearest_delta_ms = (delta + 999999) / 1000000;
727
    if (nearest_delta_ms < 1) {
728
        nearest_delta_ms = 1;
729
    }
730

    
731
    timeKillEvent(mm_timer);
732
    mm_timer = timeSetEvent(nearest_delta_ms,
733
                            mm_period,
734
                            mm_alarm_handler,
735
                            (DWORD_PTR)t,
736
                            TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
737

    
738
    if (!mm_timer) {
739
        fprintf(stderr, "Failed to re-arm win32 alarm timer %ld\n",
740
                GetLastError());
741

    
742
        timeEndPeriod(mm_period);
743
        exit(1);
744
    }
745
}
746

    
747
static int win32_start_timer(struct qemu_alarm_timer *t)
748
{
749
    HANDLE hTimer;
750
    BOOLEAN success;
751

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

    
764
    if (!success) {
765
        fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
766
                GetLastError());
767
        return -1;
768
    }
769

    
770
    t->timer = hTimer;
771
    return 0;
772
}
773

    
774
static void win32_stop_timer(struct qemu_alarm_timer *t)
775
{
776
    HANDLE hTimer = t->timer;
777

    
778
    if (hTimer) {
779
        DeleteTimerQueueTimer(NULL, hTimer, NULL);
780
    }
781
}
782

    
783
static void win32_rearm_timer(struct qemu_alarm_timer *t,
784
                              int64_t nearest_delta_ns)
785
{
786
    HANDLE hTimer = t->timer;
787
    int nearest_delta_ms;
788
    BOOLEAN success;
789

    
790
    nearest_delta_ms = (nearest_delta_ns + 999999) / 1000000;
791
    if (nearest_delta_ms < 1) {
792
        nearest_delta_ms = 1;
793
    }
794
    success = ChangeTimerQueueTimer(NULL,
795
                                    hTimer,
796
                                    nearest_delta_ms,
797
                                    3600000);
798

    
799
    if (!success) {
800
        fprintf(stderr, "Failed to rearm win32 alarm timer: %ld\n",
801
                GetLastError());
802
        exit(-1);
803
    }
804

    
805
}
806

    
807
#endif /* _WIN32 */
808

    
809
static void alarm_timer_on_change_state_rearm(void *opaque, int running,
810
                                              RunState state)
811
{
812
    if (running)
813
        qemu_rearm_alarm_timer((struct qemu_alarm_timer *) opaque);
814
}
815

    
816
static void quit_timers(void)
817
{
818
    struct qemu_alarm_timer *t = alarm_timer;
819
    alarm_timer = NULL;
820
    t->stop(t);
821
}
822

    
823
int init_timer_alarm(void)
824
{
825
    struct qemu_alarm_timer *t = NULL;
826
    int i, err = -1;
827

    
828
    for (i = 0; alarm_timers[i].name; i++) {
829
        t = &alarm_timers[i];
830

    
831
        err = t->start(t);
832
        if (!err)
833
            break;
834
    }
835

    
836
    if (err) {
837
        err = -ENOENT;
838
        goto fail;
839
    }
840

    
841
    /* first event is at time 0 */
842
    atexit(quit_timers);
843
    t->pending = 1;
844
    alarm_timer = t;
845
    qemu_add_vm_change_state_handler(alarm_timer_on_change_state_rearm, t);
846

    
847
    return 0;
848

    
849
fail:
850
    return err;
851
}
852

    
853
int qemu_calculate_timeout(void)
854
{
855
    return 1000;
856
}
857