Statistics
| Branch: | Revision:

root / qemu-timer.c @ 2ff68d07

History | View | Annotate | Download (21 kB)

1 db1a4972 Paolo Bonzini
/*
2 db1a4972 Paolo Bonzini
 * QEMU System Emulator
3 db1a4972 Paolo Bonzini
 *
4 db1a4972 Paolo Bonzini
 * Copyright (c) 2003-2008 Fabrice Bellard
5 db1a4972 Paolo Bonzini
 *
6 db1a4972 Paolo Bonzini
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 db1a4972 Paolo Bonzini
 * of this software and associated documentation files (the "Software"), to deal
8 db1a4972 Paolo Bonzini
 * in the Software without restriction, including without limitation the rights
9 db1a4972 Paolo Bonzini
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 db1a4972 Paolo Bonzini
 * copies of the Software, and to permit persons to whom the Software is
11 db1a4972 Paolo Bonzini
 * furnished to do so, subject to the following conditions:
12 db1a4972 Paolo Bonzini
 *
13 db1a4972 Paolo Bonzini
 * The above copyright notice and this permission notice shall be included in
14 db1a4972 Paolo Bonzini
 * all copies or substantial portions of the Software.
15 db1a4972 Paolo Bonzini
 *
16 db1a4972 Paolo Bonzini
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 db1a4972 Paolo Bonzini
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 db1a4972 Paolo Bonzini
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 db1a4972 Paolo Bonzini
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 db1a4972 Paolo Bonzini
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 db1a4972 Paolo Bonzini
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 db1a4972 Paolo Bonzini
 * THE SOFTWARE.
23 db1a4972 Paolo Bonzini
 */
24 db1a4972 Paolo Bonzini
25 db1a4972 Paolo Bonzini
#include "sysemu.h"
26 db1a4972 Paolo Bonzini
#include "net.h"
27 db1a4972 Paolo Bonzini
#include "monitor.h"
28 db1a4972 Paolo Bonzini
#include "console.h"
29 db1a4972 Paolo Bonzini
30 db1a4972 Paolo Bonzini
#include "hw/hw.h"
31 db1a4972 Paolo Bonzini
32 db1a4972 Paolo Bonzini
#include <unistd.h>
33 db1a4972 Paolo Bonzini
#include <fcntl.h>
34 db1a4972 Paolo Bonzini
#include <time.h>
35 db1a4972 Paolo Bonzini
#include <errno.h>
36 db1a4972 Paolo Bonzini
#include <sys/time.h>
37 db1a4972 Paolo Bonzini
#include <signal.h>
38 44459349 Juergen Lock
#ifdef __FreeBSD__
39 44459349 Juergen Lock
#include <sys/param.h>
40 44459349 Juergen Lock
#endif
41 db1a4972 Paolo Bonzini
42 db1a4972 Paolo Bonzini
#ifdef _WIN32
43 db1a4972 Paolo Bonzini
#include <windows.h>
44 db1a4972 Paolo Bonzini
#include <mmsystem.h>
45 db1a4972 Paolo Bonzini
#endif
46 db1a4972 Paolo Bonzini
47 db1a4972 Paolo Bonzini
#include "qemu-timer.h"
48 db1a4972 Paolo Bonzini
49 db1a4972 Paolo Bonzini
/***********************************************************/
50 db1a4972 Paolo Bonzini
/* timers */
51 db1a4972 Paolo Bonzini
52 db1a4972 Paolo Bonzini
#define QEMU_CLOCK_REALTIME 0
53 db1a4972 Paolo Bonzini
#define QEMU_CLOCK_VIRTUAL  1
54 db1a4972 Paolo Bonzini
#define QEMU_CLOCK_HOST     2
55 db1a4972 Paolo Bonzini
56 db1a4972 Paolo Bonzini
struct QEMUClock {
57 db1a4972 Paolo Bonzini
    int type;
58 db1a4972 Paolo Bonzini
    int enabled;
59 ab33fcda Paolo Bonzini
60 688eb389 Paolo Bonzini
    QEMUTimer *active_timers;
61 691a0c9c Jan Kiszka
62 691a0c9c Jan Kiszka
    NotifierList reset_notifiers;
63 691a0c9c Jan Kiszka
    int64_t last;
64 db1a4972 Paolo Bonzini
};
65 db1a4972 Paolo Bonzini
66 db1a4972 Paolo Bonzini
struct QEMUTimer {
67 db1a4972 Paolo Bonzini
    QEMUClock *clock;
68 4a998740 Paolo Bonzini
    int64_t expire_time;        /* in nanoseconds */
69 4a998740 Paolo Bonzini
    int scale;
70 db1a4972 Paolo Bonzini
    QEMUTimerCB *cb;
71 db1a4972 Paolo Bonzini
    void *opaque;
72 db1a4972 Paolo Bonzini
    struct QEMUTimer *next;
73 db1a4972 Paolo Bonzini
};
74 db1a4972 Paolo Bonzini
75 db1a4972 Paolo Bonzini
struct qemu_alarm_timer {
76 db1a4972 Paolo Bonzini
    char const *name;
77 db1a4972 Paolo Bonzini
    int (*start)(struct qemu_alarm_timer *t);
78 db1a4972 Paolo Bonzini
    void (*stop)(struct qemu_alarm_timer *t);
79 f3fc6e2e Paolo Bonzini
    void (*rearm)(struct qemu_alarm_timer *t, int64_t nearest_delta_ns);
80 cd0544ee Stefan Weil
#if defined(__linux__)
81 cd0544ee Stefan Weil
    int fd;
82 cd0544ee Stefan Weil
    timer_t timer;
83 cd0544ee Stefan Weil
#elif defined(_WIN32)
84 cd0544ee Stefan Weil
    HANDLE timer;
85 cd0544ee Stefan Weil
#endif
86 db1a4972 Paolo Bonzini
    char expired;
87 db1a4972 Paolo Bonzini
    char pending;
88 db1a4972 Paolo Bonzini
};
89 db1a4972 Paolo Bonzini
90 db1a4972 Paolo Bonzini
static struct qemu_alarm_timer *alarm_timer;
91 db1a4972 Paolo Bonzini
92 45c7b37f Stefan Weil
static bool qemu_timer_expired_ns(QEMUTimer *timer_head, int64_t current_time)
93 45c7b37f Stefan Weil
{
94 45c7b37f Stefan Weil
    return timer_head && (timer_head->expire_time <= current_time);
95 45c7b37f Stefan Weil
}
96 45c7b37f Stefan Weil
97 db1a4972 Paolo Bonzini
int qemu_alarm_pending(void)
98 db1a4972 Paolo Bonzini
{
99 db1a4972 Paolo Bonzini
    return alarm_timer->pending;
100 db1a4972 Paolo Bonzini
}
101 db1a4972 Paolo Bonzini
102 db1a4972 Paolo Bonzini
static inline int alarm_has_dynticks(struct qemu_alarm_timer *t)
103 db1a4972 Paolo Bonzini
{
104 db1a4972 Paolo Bonzini
    return !!t->rearm;
105 db1a4972 Paolo Bonzini
}
106 db1a4972 Paolo Bonzini
107 f3fc6e2e Paolo Bonzini
static int64_t qemu_next_alarm_deadline(void)
108 f3fc6e2e Paolo Bonzini
{
109 f3fc6e2e Paolo Bonzini
    int64_t delta;
110 f3fc6e2e Paolo Bonzini
    int64_t rtdelta;
111 f3fc6e2e Paolo Bonzini
112 f3fc6e2e Paolo Bonzini
    if (!use_icount && vm_clock->active_timers) {
113 f3fc6e2e Paolo Bonzini
        delta = vm_clock->active_timers->expire_time -
114 f3fc6e2e Paolo Bonzini
                     qemu_get_clock_ns(vm_clock);
115 f3fc6e2e Paolo Bonzini
    } else {
116 f3fc6e2e Paolo Bonzini
        delta = INT32_MAX;
117 f3fc6e2e Paolo Bonzini
    }
118 f3fc6e2e Paolo Bonzini
    if (host_clock->active_timers) {
119 f3fc6e2e Paolo Bonzini
        int64_t hdelta = host_clock->active_timers->expire_time -
120 f3fc6e2e Paolo Bonzini
                 qemu_get_clock_ns(host_clock);
121 f3fc6e2e Paolo Bonzini
        if (hdelta < delta) {
122 f3fc6e2e Paolo Bonzini
            delta = hdelta;
123 f3fc6e2e Paolo Bonzini
        }
124 f3fc6e2e Paolo Bonzini
    }
125 f3fc6e2e Paolo Bonzini
    if (rt_clock->active_timers) {
126 f3fc6e2e Paolo Bonzini
        rtdelta = (rt_clock->active_timers->expire_time -
127 f3fc6e2e Paolo Bonzini
                 qemu_get_clock_ns(rt_clock));
128 f3fc6e2e Paolo Bonzini
        if (rtdelta < delta) {
129 f3fc6e2e Paolo Bonzini
            delta = rtdelta;
130 f3fc6e2e Paolo Bonzini
        }
131 f3fc6e2e Paolo Bonzini
    }
132 f3fc6e2e Paolo Bonzini
133 f3fc6e2e Paolo Bonzini
    return delta;
134 f3fc6e2e Paolo Bonzini
}
135 f3fc6e2e Paolo Bonzini
136 db1a4972 Paolo Bonzini
static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
137 db1a4972 Paolo Bonzini
{
138 f3fc6e2e Paolo Bonzini
    int64_t nearest_delta_ns;
139 f3fc6e2e Paolo Bonzini
    assert(alarm_has_dynticks(t));
140 f3fc6e2e Paolo Bonzini
    if (!rt_clock->active_timers &&
141 f3fc6e2e Paolo Bonzini
        !vm_clock->active_timers &&
142 f3fc6e2e Paolo Bonzini
        !host_clock->active_timers) {
143 db1a4972 Paolo Bonzini
        return;
144 f3fc6e2e Paolo Bonzini
    }
145 f3fc6e2e Paolo Bonzini
    nearest_delta_ns = qemu_next_alarm_deadline();
146 f3fc6e2e Paolo Bonzini
    t->rearm(t, nearest_delta_ns);
147 db1a4972 Paolo Bonzini
}
148 db1a4972 Paolo Bonzini
149 9c13246a Paolo Bonzini
/* TODO: MIN_TIMER_REARM_NS should be optimized */
150 9c13246a Paolo Bonzini
#define MIN_TIMER_REARM_NS 250000
151 db1a4972 Paolo Bonzini
152 db1a4972 Paolo Bonzini
#ifdef _WIN32
153 db1a4972 Paolo Bonzini
154 2f9cba0c Stefan Weil
static int mm_start_timer(struct qemu_alarm_timer *t);
155 2f9cba0c Stefan Weil
static void mm_stop_timer(struct qemu_alarm_timer *t);
156 f3fc6e2e Paolo Bonzini
static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
157 2f9cba0c Stefan Weil
158 db1a4972 Paolo Bonzini
static int win32_start_timer(struct qemu_alarm_timer *t);
159 db1a4972 Paolo Bonzini
static void win32_stop_timer(struct qemu_alarm_timer *t);
160 f3fc6e2e Paolo Bonzini
static void win32_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
161 db1a4972 Paolo Bonzini
162 db1a4972 Paolo Bonzini
#else
163 db1a4972 Paolo Bonzini
164 db1a4972 Paolo Bonzini
static int unix_start_timer(struct qemu_alarm_timer *t);
165 db1a4972 Paolo Bonzini
static void unix_stop_timer(struct qemu_alarm_timer *t);
166 f3fc6e2e Paolo Bonzini
static void unix_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
167 db1a4972 Paolo Bonzini
168 db1a4972 Paolo Bonzini
#ifdef __linux__
169 db1a4972 Paolo Bonzini
170 db1a4972 Paolo Bonzini
static int dynticks_start_timer(struct qemu_alarm_timer *t);
171 db1a4972 Paolo Bonzini
static void dynticks_stop_timer(struct qemu_alarm_timer *t);
172 f3fc6e2e Paolo Bonzini
static void dynticks_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
173 db1a4972 Paolo Bonzini
174 db1a4972 Paolo Bonzini
#endif /* __linux__ */
175 db1a4972 Paolo Bonzini
176 db1a4972 Paolo Bonzini
#endif /* _WIN32 */
177 db1a4972 Paolo Bonzini
178 db1a4972 Paolo Bonzini
static struct qemu_alarm_timer alarm_timers[] = {
179 db1a4972 Paolo Bonzini
#ifndef _WIN32
180 db1a4972 Paolo Bonzini
#ifdef __linux__
181 db1a4972 Paolo Bonzini
    {"dynticks", dynticks_start_timer,
182 cd0544ee Stefan Weil
     dynticks_stop_timer, dynticks_rearm_timer},
183 db1a4972 Paolo Bonzini
#endif
184 84682834 Paolo Bonzini
    {"unix", unix_start_timer, unix_stop_timer, unix_rearm_timer},
185 db1a4972 Paolo Bonzini
#else
186 2f9cba0c Stefan Weil
    {"mmtimer", mm_start_timer, mm_stop_timer, NULL},
187 2f9cba0c Stefan Weil
    {"mmtimer2", mm_start_timer, mm_stop_timer, mm_rearm_timer},
188 cd0544ee Stefan Weil
    {"dynticks", win32_start_timer, win32_stop_timer, win32_rearm_timer},
189 cd0544ee Stefan Weil
    {"win32", win32_start_timer, win32_stop_timer, NULL},
190 db1a4972 Paolo Bonzini
#endif
191 db1a4972 Paolo Bonzini
    {NULL, }
192 db1a4972 Paolo Bonzini
};
193 db1a4972 Paolo Bonzini
194 db1a4972 Paolo Bonzini
static void show_available_alarms(void)
195 db1a4972 Paolo Bonzini
{
196 db1a4972 Paolo Bonzini
    int i;
197 db1a4972 Paolo Bonzini
198 db1a4972 Paolo Bonzini
    printf("Available alarm timers, in order of precedence:\n");
199 db1a4972 Paolo Bonzini
    for (i = 0; alarm_timers[i].name; i++)
200 db1a4972 Paolo Bonzini
        printf("%s\n", alarm_timers[i].name);
201 db1a4972 Paolo Bonzini
}
202 db1a4972 Paolo Bonzini
203 db1a4972 Paolo Bonzini
void configure_alarms(char const *opt)
204 db1a4972 Paolo Bonzini
{
205 db1a4972 Paolo Bonzini
    int i;
206 db1a4972 Paolo Bonzini
    int cur = 0;
207 db1a4972 Paolo Bonzini
    int count = ARRAY_SIZE(alarm_timers) - 1;
208 db1a4972 Paolo Bonzini
    char *arg;
209 db1a4972 Paolo Bonzini
    char *name;
210 db1a4972 Paolo Bonzini
    struct qemu_alarm_timer tmp;
211 db1a4972 Paolo Bonzini
212 db1a4972 Paolo Bonzini
    if (!strcmp(opt, "?")) {
213 db1a4972 Paolo Bonzini
        show_available_alarms();
214 db1a4972 Paolo Bonzini
        exit(0);
215 db1a4972 Paolo Bonzini
    }
216 db1a4972 Paolo Bonzini
217 7267c094 Anthony Liguori
    arg = g_strdup(opt);
218 db1a4972 Paolo Bonzini
219 db1a4972 Paolo Bonzini
    /* Reorder the array */
220 db1a4972 Paolo Bonzini
    name = strtok(arg, ",");
221 db1a4972 Paolo Bonzini
    while (name) {
222 db1a4972 Paolo Bonzini
        for (i = 0; i < count && alarm_timers[i].name; i++) {
223 db1a4972 Paolo Bonzini
            if (!strcmp(alarm_timers[i].name, name))
224 db1a4972 Paolo Bonzini
                break;
225 db1a4972 Paolo Bonzini
        }
226 db1a4972 Paolo Bonzini
227 db1a4972 Paolo Bonzini
        if (i == count) {
228 db1a4972 Paolo Bonzini
            fprintf(stderr, "Unknown clock %s\n", name);
229 db1a4972 Paolo Bonzini
            goto next;
230 db1a4972 Paolo Bonzini
        }
231 db1a4972 Paolo Bonzini
232 db1a4972 Paolo Bonzini
        if (i < cur)
233 db1a4972 Paolo Bonzini
            /* Ignore */
234 db1a4972 Paolo Bonzini
            goto next;
235 db1a4972 Paolo Bonzini
236 db1a4972 Paolo Bonzini
        /* Swap */
237 db1a4972 Paolo Bonzini
        tmp = alarm_timers[i];
238 db1a4972 Paolo Bonzini
        alarm_timers[i] = alarm_timers[cur];
239 db1a4972 Paolo Bonzini
        alarm_timers[cur] = tmp;
240 db1a4972 Paolo Bonzini
241 db1a4972 Paolo Bonzini
        cur++;
242 db1a4972 Paolo Bonzini
next:
243 db1a4972 Paolo Bonzini
        name = strtok(NULL, ",");
244 db1a4972 Paolo Bonzini
    }
245 db1a4972 Paolo Bonzini
246 7267c094 Anthony Liguori
    g_free(arg);
247 db1a4972 Paolo Bonzini
248 db1a4972 Paolo Bonzini
    if (cur) {
249 db1a4972 Paolo Bonzini
        /* Disable remaining timers */
250 db1a4972 Paolo Bonzini
        for (i = cur; i < count; i++)
251 db1a4972 Paolo Bonzini
            alarm_timers[i].name = NULL;
252 db1a4972 Paolo Bonzini
    } else {
253 db1a4972 Paolo Bonzini
        show_available_alarms();
254 db1a4972 Paolo Bonzini
        exit(1);
255 db1a4972 Paolo Bonzini
    }
256 db1a4972 Paolo Bonzini
}
257 db1a4972 Paolo Bonzini
258 db1a4972 Paolo Bonzini
QEMUClock *rt_clock;
259 db1a4972 Paolo Bonzini
QEMUClock *vm_clock;
260 db1a4972 Paolo Bonzini
QEMUClock *host_clock;
261 db1a4972 Paolo Bonzini
262 db1a4972 Paolo Bonzini
static QEMUClock *qemu_new_clock(int type)
263 db1a4972 Paolo Bonzini
{
264 db1a4972 Paolo Bonzini
    QEMUClock *clock;
265 691a0c9c Jan Kiszka
266 7267c094 Anthony Liguori
    clock = g_malloc0(sizeof(QEMUClock));
267 db1a4972 Paolo Bonzini
    clock->type = type;
268 db1a4972 Paolo Bonzini
    clock->enabled = 1;
269 2ff68d07 Paolo Bonzini
    clock->last = INT64_MIN;
270 691a0c9c Jan Kiszka
    notifier_list_init(&clock->reset_notifiers);
271 db1a4972 Paolo Bonzini
    return clock;
272 db1a4972 Paolo Bonzini
}
273 db1a4972 Paolo Bonzini
274 db1a4972 Paolo Bonzini
void qemu_clock_enable(QEMUClock *clock, int enabled)
275 db1a4972 Paolo Bonzini
{
276 db1a4972 Paolo Bonzini
    clock->enabled = enabled;
277 db1a4972 Paolo Bonzini
}
278 db1a4972 Paolo Bonzini
279 dc2dfcf0 Paolo Bonzini
int64_t qemu_clock_has_timers(QEMUClock *clock)
280 dc2dfcf0 Paolo Bonzini
{
281 dc2dfcf0 Paolo Bonzini
    return !!clock->active_timers;
282 dc2dfcf0 Paolo Bonzini
}
283 dc2dfcf0 Paolo Bonzini
284 dc2dfcf0 Paolo Bonzini
int64_t qemu_clock_expired(QEMUClock *clock)
285 dc2dfcf0 Paolo Bonzini
{
286 dc2dfcf0 Paolo Bonzini
    return (clock->active_timers &&
287 dc2dfcf0 Paolo Bonzini
            clock->active_timers->expire_time < qemu_get_clock_ns(clock));
288 dc2dfcf0 Paolo Bonzini
}
289 dc2dfcf0 Paolo Bonzini
290 dc2dfcf0 Paolo Bonzini
int64_t qemu_clock_deadline(QEMUClock *clock)
291 dc2dfcf0 Paolo Bonzini
{
292 dc2dfcf0 Paolo Bonzini
    /* To avoid problems with overflow limit this to 2^32.  */
293 dc2dfcf0 Paolo Bonzini
    int64_t delta = INT32_MAX;
294 dc2dfcf0 Paolo Bonzini
295 dc2dfcf0 Paolo Bonzini
    if (clock->active_timers) {
296 dc2dfcf0 Paolo Bonzini
        delta = clock->active_timers->expire_time - qemu_get_clock_ns(clock);
297 dc2dfcf0 Paolo Bonzini
    }
298 dc2dfcf0 Paolo Bonzini
    if (delta < 0) {
299 dc2dfcf0 Paolo Bonzini
        delta = 0;
300 dc2dfcf0 Paolo Bonzini
    }
301 dc2dfcf0 Paolo Bonzini
    return delta;
302 dc2dfcf0 Paolo Bonzini
}
303 dc2dfcf0 Paolo Bonzini
304 4a998740 Paolo Bonzini
QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
305 4a998740 Paolo Bonzini
                          QEMUTimerCB *cb, void *opaque)
306 db1a4972 Paolo Bonzini
{
307 db1a4972 Paolo Bonzini
    QEMUTimer *ts;
308 db1a4972 Paolo Bonzini
309 7267c094 Anthony Liguori
    ts = g_malloc0(sizeof(QEMUTimer));
310 db1a4972 Paolo Bonzini
    ts->clock = clock;
311 db1a4972 Paolo Bonzini
    ts->cb = cb;
312 db1a4972 Paolo Bonzini
    ts->opaque = opaque;
313 4a998740 Paolo Bonzini
    ts->scale = scale;
314 db1a4972 Paolo Bonzini
    return ts;
315 db1a4972 Paolo Bonzini
}
316 db1a4972 Paolo Bonzini
317 db1a4972 Paolo Bonzini
void qemu_free_timer(QEMUTimer *ts)
318 db1a4972 Paolo Bonzini
{
319 7267c094 Anthony Liguori
    g_free(ts);
320 db1a4972 Paolo Bonzini
}
321 db1a4972 Paolo Bonzini
322 db1a4972 Paolo Bonzini
/* stop a timer, but do not dealloc it */
323 db1a4972 Paolo Bonzini
void qemu_del_timer(QEMUTimer *ts)
324 db1a4972 Paolo Bonzini
{
325 db1a4972 Paolo Bonzini
    QEMUTimer **pt, *t;
326 db1a4972 Paolo Bonzini
327 db1a4972 Paolo Bonzini
    /* NOTE: this code must be signal safe because
328 db1a4972 Paolo Bonzini
       qemu_timer_expired() can be called from a signal. */
329 688eb389 Paolo Bonzini
    pt = &ts->clock->active_timers;
330 db1a4972 Paolo Bonzini
    for(;;) {
331 db1a4972 Paolo Bonzini
        t = *pt;
332 db1a4972 Paolo Bonzini
        if (!t)
333 db1a4972 Paolo Bonzini
            break;
334 db1a4972 Paolo Bonzini
        if (t == ts) {
335 db1a4972 Paolo Bonzini
            *pt = t->next;
336 db1a4972 Paolo Bonzini
            break;
337 db1a4972 Paolo Bonzini
        }
338 db1a4972 Paolo Bonzini
        pt = &t->next;
339 db1a4972 Paolo Bonzini
    }
340 db1a4972 Paolo Bonzini
}
341 db1a4972 Paolo Bonzini
342 db1a4972 Paolo Bonzini
/* modify the current timer so that it will be fired when current_time
343 db1a4972 Paolo Bonzini
   >= expire_time. The corresponding callback will be called. */
344 2ff68d07 Paolo Bonzini
void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)
345 db1a4972 Paolo Bonzini
{
346 db1a4972 Paolo Bonzini
    QEMUTimer **pt, *t;
347 db1a4972 Paolo Bonzini
348 db1a4972 Paolo Bonzini
    qemu_del_timer(ts);
349 db1a4972 Paolo Bonzini
350 db1a4972 Paolo Bonzini
    /* add the timer in the sorted list */
351 db1a4972 Paolo Bonzini
    /* NOTE: this code must be signal safe because
352 db1a4972 Paolo Bonzini
       qemu_timer_expired() can be called from a signal. */
353 688eb389 Paolo Bonzini
    pt = &ts->clock->active_timers;
354 db1a4972 Paolo Bonzini
    for(;;) {
355 db1a4972 Paolo Bonzini
        t = *pt;
356 45c7b37f Stefan Weil
        if (!qemu_timer_expired_ns(t, expire_time)) {
357 db1a4972 Paolo Bonzini
            break;
358 45c7b37f Stefan Weil
        }
359 db1a4972 Paolo Bonzini
        pt = &t->next;
360 db1a4972 Paolo Bonzini
    }
361 db1a4972 Paolo Bonzini
    ts->expire_time = expire_time;
362 db1a4972 Paolo Bonzini
    ts->next = *pt;
363 db1a4972 Paolo Bonzini
    *pt = ts;
364 db1a4972 Paolo Bonzini
365 db1a4972 Paolo Bonzini
    /* Rearm if necessary  */
366 688eb389 Paolo Bonzini
    if (pt == &ts->clock->active_timers) {
367 db1a4972 Paolo Bonzini
        if (!alarm_timer->pending) {
368 db1a4972 Paolo Bonzini
            qemu_rearm_alarm_timer(alarm_timer);
369 db1a4972 Paolo Bonzini
        }
370 db1a4972 Paolo Bonzini
        /* Interrupt execution to force deadline recalculation.  */
371 ab33fcda Paolo Bonzini
        qemu_clock_warp(ts->clock);
372 ab33fcda Paolo Bonzini
        if (use_icount) {
373 db1a4972 Paolo Bonzini
            qemu_notify_event();
374 ab33fcda Paolo Bonzini
        }
375 db1a4972 Paolo Bonzini
    }
376 db1a4972 Paolo Bonzini
}
377 db1a4972 Paolo Bonzini
378 4a998740 Paolo Bonzini
void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
379 4a998740 Paolo Bonzini
{
380 4a998740 Paolo Bonzini
    qemu_mod_timer_ns(ts, expire_time * ts->scale);
381 4a998740 Paolo Bonzini
}
382 4a998740 Paolo Bonzini
383 db1a4972 Paolo Bonzini
int qemu_timer_pending(QEMUTimer *ts)
384 db1a4972 Paolo Bonzini
{
385 db1a4972 Paolo Bonzini
    QEMUTimer *t;
386 688eb389 Paolo Bonzini
    for (t = ts->clock->active_timers; t != NULL; t = t->next) {
387 db1a4972 Paolo Bonzini
        if (t == ts)
388 db1a4972 Paolo Bonzini
            return 1;
389 db1a4972 Paolo Bonzini
    }
390 db1a4972 Paolo Bonzini
    return 0;
391 db1a4972 Paolo Bonzini
}
392 db1a4972 Paolo Bonzini
393 db1a4972 Paolo Bonzini
int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
394 db1a4972 Paolo Bonzini
{
395 45c7b37f Stefan Weil
    return qemu_timer_expired_ns(timer_head, current_time * timer_head->scale);
396 db1a4972 Paolo Bonzini
}
397 db1a4972 Paolo Bonzini
398 db1a4972 Paolo Bonzini
static void qemu_run_timers(QEMUClock *clock)
399 db1a4972 Paolo Bonzini
{
400 db1a4972 Paolo Bonzini
    QEMUTimer **ptimer_head, *ts;
401 db1a4972 Paolo Bonzini
    int64_t current_time;
402 db1a4972 Paolo Bonzini
   
403 db1a4972 Paolo Bonzini
    if (!clock->enabled)
404 db1a4972 Paolo Bonzini
        return;
405 db1a4972 Paolo Bonzini
406 4a998740 Paolo Bonzini
    current_time = qemu_get_clock_ns(clock);
407 688eb389 Paolo Bonzini
    ptimer_head = &clock->active_timers;
408 db1a4972 Paolo Bonzini
    for(;;) {
409 db1a4972 Paolo Bonzini
        ts = *ptimer_head;
410 45c7b37f Stefan Weil
        if (!qemu_timer_expired_ns(ts, current_time)) {
411 db1a4972 Paolo Bonzini
            break;
412 45c7b37f Stefan Weil
        }
413 db1a4972 Paolo Bonzini
        /* remove timer from the list before calling the callback */
414 db1a4972 Paolo Bonzini
        *ptimer_head = ts->next;
415 db1a4972 Paolo Bonzini
        ts->next = NULL;
416 db1a4972 Paolo Bonzini
417 db1a4972 Paolo Bonzini
        /* run the callback (the timer list can be modified) */
418 db1a4972 Paolo Bonzini
        ts->cb(ts->opaque);
419 db1a4972 Paolo Bonzini
    }
420 db1a4972 Paolo Bonzini
}
421 db1a4972 Paolo Bonzini
422 db1a4972 Paolo Bonzini
int64_t qemu_get_clock_ns(QEMUClock *clock)
423 db1a4972 Paolo Bonzini
{
424 691a0c9c Jan Kiszka
    int64_t now, last;
425 691a0c9c Jan Kiszka
426 db1a4972 Paolo Bonzini
    switch(clock->type) {
427 db1a4972 Paolo Bonzini
    case QEMU_CLOCK_REALTIME:
428 db1a4972 Paolo Bonzini
        return get_clock();
429 db1a4972 Paolo Bonzini
    default:
430 db1a4972 Paolo Bonzini
    case QEMU_CLOCK_VIRTUAL:
431 db1a4972 Paolo Bonzini
        if (use_icount) {
432 db1a4972 Paolo Bonzini
            return cpu_get_icount();
433 db1a4972 Paolo Bonzini
        } else {
434 db1a4972 Paolo Bonzini
            return cpu_get_clock();
435 db1a4972 Paolo Bonzini
        }
436 db1a4972 Paolo Bonzini
    case QEMU_CLOCK_HOST:
437 691a0c9c Jan Kiszka
        now = get_clock_realtime();
438 691a0c9c Jan Kiszka
        last = clock->last;
439 691a0c9c Jan Kiszka
        clock->last = now;
440 691a0c9c Jan Kiszka
        if (now < last) {
441 691a0c9c Jan Kiszka
            notifier_list_notify(&clock->reset_notifiers, &now);
442 691a0c9c Jan Kiszka
        }
443 691a0c9c Jan Kiszka
        return now;
444 db1a4972 Paolo Bonzini
    }
445 db1a4972 Paolo Bonzini
}
446 db1a4972 Paolo Bonzini
447 691a0c9c Jan Kiszka
void qemu_register_clock_reset_notifier(QEMUClock *clock, Notifier *notifier)
448 691a0c9c Jan Kiszka
{
449 691a0c9c Jan Kiszka
    notifier_list_add(&clock->reset_notifiers, notifier);
450 691a0c9c Jan Kiszka
}
451 691a0c9c Jan Kiszka
452 691a0c9c Jan Kiszka
void qemu_unregister_clock_reset_notifier(QEMUClock *clock, Notifier *notifier)
453 691a0c9c Jan Kiszka
{
454 691a0c9c Jan Kiszka
    notifier_list_remove(&clock->reset_notifiers, notifier);
455 691a0c9c Jan Kiszka
}
456 691a0c9c Jan Kiszka
457 db1a4972 Paolo Bonzini
void init_clocks(void)
458 db1a4972 Paolo Bonzini
{
459 db1a4972 Paolo Bonzini
    rt_clock = qemu_new_clock(QEMU_CLOCK_REALTIME);
460 db1a4972 Paolo Bonzini
    vm_clock = qemu_new_clock(QEMU_CLOCK_VIRTUAL);
461 db1a4972 Paolo Bonzini
    host_clock = qemu_new_clock(QEMU_CLOCK_HOST);
462 db1a4972 Paolo Bonzini
}
463 db1a4972 Paolo Bonzini
464 2ff68d07 Paolo Bonzini
uint64_t qemu_timer_expire_time_ns(QEMUTimer *ts)
465 db1a4972 Paolo Bonzini
{
466 2ff68d07 Paolo Bonzini
    return qemu_timer_pending(ts) ? ts->expire_time : -1;
467 db1a4972 Paolo Bonzini
}
468 db1a4972 Paolo Bonzini
469 db1a4972 Paolo Bonzini
void qemu_run_all_timers(void)
470 db1a4972 Paolo Bonzini
{
471 ca5a2a4b Paolo Bonzini
    alarm_timer->pending = 0;
472 ca5a2a4b Paolo Bonzini
473 db1a4972 Paolo Bonzini
    /* rearm timer, if not periodic */
474 db1a4972 Paolo Bonzini
    if (alarm_timer->expired) {
475 db1a4972 Paolo Bonzini
        alarm_timer->expired = 0;
476 db1a4972 Paolo Bonzini
        qemu_rearm_alarm_timer(alarm_timer);
477 db1a4972 Paolo Bonzini
    }
478 db1a4972 Paolo Bonzini
479 db1a4972 Paolo Bonzini
    /* vm time timers */
480 a5c57d64 Paolo Bonzini
    qemu_run_timers(vm_clock);
481 db1a4972 Paolo Bonzini
    qemu_run_timers(rt_clock);
482 db1a4972 Paolo Bonzini
    qemu_run_timers(host_clock);
483 db1a4972 Paolo Bonzini
}
484 db1a4972 Paolo Bonzini
485 db1a4972 Paolo Bonzini
#ifdef _WIN32
486 68c23e55 Paolo Bonzini
static void CALLBACK host_alarm_handler(PVOID lpParam, BOOLEAN unused)
487 db1a4972 Paolo Bonzini
#else
488 db1a4972 Paolo Bonzini
static void host_alarm_handler(int host_signum)
489 db1a4972 Paolo Bonzini
#endif
490 db1a4972 Paolo Bonzini
{
491 db1a4972 Paolo Bonzini
    struct qemu_alarm_timer *t = alarm_timer;
492 db1a4972 Paolo Bonzini
    if (!t)
493 db1a4972 Paolo Bonzini
        return;
494 db1a4972 Paolo Bonzini
495 db1a4972 Paolo Bonzini
#if 0
496 db1a4972 Paolo Bonzini
#define DISP_FREQ 1000
497 db1a4972 Paolo Bonzini
    {
498 db1a4972 Paolo Bonzini
        static int64_t delta_min = INT64_MAX;
499 db1a4972 Paolo Bonzini
        static int64_t delta_max, delta_cum, last_clock, delta, ti;
500 db1a4972 Paolo Bonzini
        static int count;
501 74475455 Paolo Bonzini
        ti = qemu_get_clock_ns(vm_clock);
502 db1a4972 Paolo Bonzini
        if (last_clock != 0) {
503 db1a4972 Paolo Bonzini
            delta = ti - last_clock;
504 db1a4972 Paolo Bonzini
            if (delta < delta_min)
505 db1a4972 Paolo Bonzini
                delta_min = delta;
506 db1a4972 Paolo Bonzini
            if (delta > delta_max)
507 db1a4972 Paolo Bonzini
                delta_max = delta;
508 db1a4972 Paolo Bonzini
            delta_cum += delta;
509 db1a4972 Paolo Bonzini
            if (++count == DISP_FREQ) {
510 db1a4972 Paolo Bonzini
                printf("timer: min=%" PRId64 " us max=%" PRId64 " us avg=%" PRId64 " us avg_freq=%0.3f Hz\n",
511 db1a4972 Paolo Bonzini
                       muldiv64(delta_min, 1000000, get_ticks_per_sec()),
512 db1a4972 Paolo Bonzini
                       muldiv64(delta_max, 1000000, get_ticks_per_sec()),
513 db1a4972 Paolo Bonzini
                       muldiv64(delta_cum, 1000000 / DISP_FREQ, get_ticks_per_sec()),
514 db1a4972 Paolo Bonzini
                       (double)get_ticks_per_sec() / ((double)delta_cum / DISP_FREQ));
515 db1a4972 Paolo Bonzini
                count = 0;
516 db1a4972 Paolo Bonzini
                delta_min = INT64_MAX;
517 db1a4972 Paolo Bonzini
                delta_max = 0;
518 db1a4972 Paolo Bonzini
                delta_cum = 0;
519 db1a4972 Paolo Bonzini
            }
520 db1a4972 Paolo Bonzini
        }
521 db1a4972 Paolo Bonzini
        last_clock = ti;
522 db1a4972 Paolo Bonzini
    }
523 db1a4972 Paolo Bonzini
#endif
524 db1a4972 Paolo Bonzini
    if (alarm_has_dynticks(t) ||
525 4c3d45eb Paolo Bonzini
        qemu_next_alarm_deadline () <= 0) {
526 db1a4972 Paolo Bonzini
        t->expired = alarm_has_dynticks(t);
527 db1a4972 Paolo Bonzini
        t->pending = 1;
528 db1a4972 Paolo Bonzini
        qemu_notify_event();
529 db1a4972 Paolo Bonzini
    }
530 db1a4972 Paolo Bonzini
}
531 db1a4972 Paolo Bonzini
532 4c3d45eb Paolo Bonzini
#if defined(__linux__)
533 4c3d45eb Paolo Bonzini
534 d25f89c9 Jan Kiszka
#include "compatfd.h"
535 d25f89c9 Jan Kiszka
536 db1a4972 Paolo Bonzini
static int dynticks_start_timer(struct qemu_alarm_timer *t)
537 db1a4972 Paolo Bonzini
{
538 db1a4972 Paolo Bonzini
    struct sigevent ev;
539 db1a4972 Paolo Bonzini
    timer_t host_timer;
540 db1a4972 Paolo Bonzini
    struct sigaction act;
541 db1a4972 Paolo Bonzini
542 db1a4972 Paolo Bonzini
    sigfillset(&act.sa_mask);
543 db1a4972 Paolo Bonzini
    act.sa_flags = 0;
544 db1a4972 Paolo Bonzini
    act.sa_handler = host_alarm_handler;
545 db1a4972 Paolo Bonzini
546 db1a4972 Paolo Bonzini
    sigaction(SIGALRM, &act, NULL);
547 db1a4972 Paolo Bonzini
548 db1a4972 Paolo Bonzini
    /* 
549 db1a4972 Paolo Bonzini
     * Initialize ev struct to 0 to avoid valgrind complaining
550 db1a4972 Paolo Bonzini
     * about uninitialized data in timer_create call
551 db1a4972 Paolo Bonzini
     */
552 db1a4972 Paolo Bonzini
    memset(&ev, 0, sizeof(ev));
553 db1a4972 Paolo Bonzini
    ev.sigev_value.sival_int = 0;
554 db1a4972 Paolo Bonzini
    ev.sigev_notify = SIGEV_SIGNAL;
555 d25f89c9 Jan Kiszka
#ifdef SIGEV_THREAD_ID
556 d25f89c9 Jan Kiszka
    if (qemu_signalfd_available()) {
557 d25f89c9 Jan Kiszka
        ev.sigev_notify = SIGEV_THREAD_ID;
558 d25f89c9 Jan Kiszka
        ev._sigev_un._tid = qemu_get_thread_id();
559 d25f89c9 Jan Kiszka
    }
560 d25f89c9 Jan Kiszka
#endif /* SIGEV_THREAD_ID */
561 db1a4972 Paolo Bonzini
    ev.sigev_signo = SIGALRM;
562 db1a4972 Paolo Bonzini
563 db1a4972 Paolo Bonzini
    if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) {
564 db1a4972 Paolo Bonzini
        perror("timer_create");
565 db1a4972 Paolo Bonzini
566 db1a4972 Paolo Bonzini
        /* disable dynticks */
567 db1a4972 Paolo Bonzini
        fprintf(stderr, "Dynamic Ticks disabled\n");
568 db1a4972 Paolo Bonzini
569 db1a4972 Paolo Bonzini
        return -1;
570 db1a4972 Paolo Bonzini
    }
571 db1a4972 Paolo Bonzini
572 cd0544ee Stefan Weil
    t->timer = host_timer;
573 db1a4972 Paolo Bonzini
574 db1a4972 Paolo Bonzini
    return 0;
575 db1a4972 Paolo Bonzini
}
576 db1a4972 Paolo Bonzini
577 db1a4972 Paolo Bonzini
static void dynticks_stop_timer(struct qemu_alarm_timer *t)
578 db1a4972 Paolo Bonzini
{
579 cd0544ee Stefan Weil
    timer_t host_timer = t->timer;
580 db1a4972 Paolo Bonzini
581 db1a4972 Paolo Bonzini
    timer_delete(host_timer);
582 db1a4972 Paolo Bonzini
}
583 db1a4972 Paolo Bonzini
584 f3fc6e2e Paolo Bonzini
static void dynticks_rearm_timer(struct qemu_alarm_timer *t,
585 f3fc6e2e Paolo Bonzini
                                 int64_t nearest_delta_ns)
586 db1a4972 Paolo Bonzini
{
587 cd0544ee Stefan Weil
    timer_t host_timer = t->timer;
588 db1a4972 Paolo Bonzini
    struct itimerspec timeout;
589 9c13246a Paolo Bonzini
    int64_t current_ns;
590 db1a4972 Paolo Bonzini
591 4c3d45eb Paolo Bonzini
    if (nearest_delta_ns < MIN_TIMER_REARM_NS)
592 4c3d45eb Paolo Bonzini
        nearest_delta_ns = MIN_TIMER_REARM_NS;
593 db1a4972 Paolo Bonzini
594 db1a4972 Paolo Bonzini
    /* check whether a timer is already running */
595 db1a4972 Paolo Bonzini
    if (timer_gettime(host_timer, &timeout)) {
596 db1a4972 Paolo Bonzini
        perror("gettime");
597 db1a4972 Paolo Bonzini
        fprintf(stderr, "Internal timer error: aborting\n");
598 db1a4972 Paolo Bonzini
        exit(1);
599 db1a4972 Paolo Bonzini
    }
600 9c13246a Paolo Bonzini
    current_ns = timeout.it_value.tv_sec * 1000000000LL + timeout.it_value.tv_nsec;
601 9c13246a Paolo Bonzini
    if (current_ns && current_ns <= nearest_delta_ns)
602 db1a4972 Paolo Bonzini
        return;
603 db1a4972 Paolo Bonzini
604 db1a4972 Paolo Bonzini
    timeout.it_interval.tv_sec = 0;
605 db1a4972 Paolo Bonzini
    timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */
606 9c13246a Paolo Bonzini
    timeout.it_value.tv_sec =  nearest_delta_ns / 1000000000;
607 9c13246a Paolo Bonzini
    timeout.it_value.tv_nsec = nearest_delta_ns % 1000000000;
608 db1a4972 Paolo Bonzini
    if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {
609 db1a4972 Paolo Bonzini
        perror("settime");
610 db1a4972 Paolo Bonzini
        fprintf(stderr, "Internal timer error: aborting\n");
611 db1a4972 Paolo Bonzini
        exit(1);
612 db1a4972 Paolo Bonzini
    }
613 db1a4972 Paolo Bonzini
}
614 db1a4972 Paolo Bonzini
615 db1a4972 Paolo Bonzini
#endif /* defined(__linux__) */
616 db1a4972 Paolo Bonzini
617 f26e5a54 Stefan Weil
#if !defined(_WIN32)
618 f26e5a54 Stefan Weil
619 db1a4972 Paolo Bonzini
static int unix_start_timer(struct qemu_alarm_timer *t)
620 db1a4972 Paolo Bonzini
{
621 db1a4972 Paolo Bonzini
    struct sigaction act;
622 db1a4972 Paolo Bonzini
623 db1a4972 Paolo Bonzini
    /* timer signal */
624 db1a4972 Paolo Bonzini
    sigfillset(&act.sa_mask);
625 db1a4972 Paolo Bonzini
    act.sa_flags = 0;
626 db1a4972 Paolo Bonzini
    act.sa_handler = host_alarm_handler;
627 db1a4972 Paolo Bonzini
628 db1a4972 Paolo Bonzini
    sigaction(SIGALRM, &act, NULL);
629 84682834 Paolo Bonzini
    return 0;
630 84682834 Paolo Bonzini
}
631 db1a4972 Paolo Bonzini
632 f3fc6e2e Paolo Bonzini
static void unix_rearm_timer(struct qemu_alarm_timer *t,
633 f3fc6e2e Paolo Bonzini
                             int64_t nearest_delta_ns)
634 84682834 Paolo Bonzini
{
635 84682834 Paolo Bonzini
    struct itimerval itv;
636 84682834 Paolo Bonzini
    int err;
637 db1a4972 Paolo Bonzini
638 84682834 Paolo Bonzini
    if (nearest_delta_ns < MIN_TIMER_REARM_NS)
639 84682834 Paolo Bonzini
        nearest_delta_ns = MIN_TIMER_REARM_NS;
640 84682834 Paolo Bonzini
641 84682834 Paolo Bonzini
    itv.it_interval.tv_sec = 0;
642 84682834 Paolo Bonzini
    itv.it_interval.tv_usec = 0; /* 0 for one-shot timer */
643 84682834 Paolo Bonzini
    itv.it_value.tv_sec =  nearest_delta_ns / 1000000000;
644 84682834 Paolo Bonzini
    itv.it_value.tv_usec = (nearest_delta_ns % 1000000000) / 1000;
645 84682834 Paolo Bonzini
    err = setitimer(ITIMER_REAL, &itv, NULL);
646 84682834 Paolo Bonzini
    if (err) {
647 84682834 Paolo Bonzini
        perror("setitimer");
648 84682834 Paolo Bonzini
        fprintf(stderr, "Internal timer error: aborting\n");
649 84682834 Paolo Bonzini
        exit(1);
650 84682834 Paolo Bonzini
    }
651 db1a4972 Paolo Bonzini
}
652 db1a4972 Paolo Bonzini
653 db1a4972 Paolo Bonzini
static void unix_stop_timer(struct qemu_alarm_timer *t)
654 db1a4972 Paolo Bonzini
{
655 db1a4972 Paolo Bonzini
    struct itimerval itv;
656 db1a4972 Paolo Bonzini
657 db1a4972 Paolo Bonzini
    memset(&itv, 0, sizeof(itv));
658 db1a4972 Paolo Bonzini
    setitimer(ITIMER_REAL, &itv, NULL);
659 db1a4972 Paolo Bonzini
}
660 db1a4972 Paolo Bonzini
661 db1a4972 Paolo Bonzini
#endif /* !defined(_WIN32) */
662 db1a4972 Paolo Bonzini
663 db1a4972 Paolo Bonzini
664 db1a4972 Paolo Bonzini
#ifdef _WIN32
665 db1a4972 Paolo Bonzini
666 2f9cba0c Stefan Weil
static MMRESULT mm_timer;
667 2f9cba0c Stefan Weil
static unsigned mm_period;
668 2f9cba0c Stefan Weil
669 2f9cba0c Stefan Weil
static void CALLBACK mm_alarm_handler(UINT uTimerID, UINT uMsg,
670 2f9cba0c Stefan Weil
                                      DWORD_PTR dwUser, DWORD_PTR dw1,
671 2f9cba0c Stefan Weil
                                      DWORD_PTR dw2)
672 2f9cba0c Stefan Weil
{
673 2f9cba0c Stefan Weil
    struct qemu_alarm_timer *t = alarm_timer;
674 2f9cba0c Stefan Weil
    if (!t) {
675 2f9cba0c Stefan Weil
        return;
676 2f9cba0c Stefan Weil
    }
677 2f9cba0c Stefan Weil
    if (alarm_has_dynticks(t) || qemu_next_alarm_deadline() <= 0) {
678 2f9cba0c Stefan Weil
        t->expired = alarm_has_dynticks(t);
679 2f9cba0c Stefan Weil
        t->pending = 1;
680 2f9cba0c Stefan Weil
        qemu_notify_event();
681 2f9cba0c Stefan Weil
    }
682 2f9cba0c Stefan Weil
}
683 2f9cba0c Stefan Weil
684 2f9cba0c Stefan Weil
static int mm_start_timer(struct qemu_alarm_timer *t)
685 2f9cba0c Stefan Weil
{
686 2f9cba0c Stefan Weil
    TIMECAPS tc;
687 2f9cba0c Stefan Weil
    UINT flags;
688 2f9cba0c Stefan Weil
689 2f9cba0c Stefan Weil
    memset(&tc, 0, sizeof(tc));
690 2f9cba0c Stefan Weil
    timeGetDevCaps(&tc, sizeof(tc));
691 2f9cba0c Stefan Weil
692 2f9cba0c Stefan Weil
    mm_period = tc.wPeriodMin;
693 2f9cba0c Stefan Weil
    timeBeginPeriod(mm_period);
694 2f9cba0c Stefan Weil
695 2f9cba0c Stefan Weil
    flags = TIME_CALLBACK_FUNCTION;
696 2f9cba0c Stefan Weil
    if (alarm_has_dynticks(t)) {
697 2f9cba0c Stefan Weil
        flags |= TIME_ONESHOT;
698 2f9cba0c Stefan Weil
    } else {
699 2f9cba0c Stefan Weil
        flags |= TIME_PERIODIC;
700 2f9cba0c Stefan Weil
    }
701 2f9cba0c Stefan Weil
702 2f9cba0c Stefan Weil
    mm_timer = timeSetEvent(1,                  /* interval (ms) */
703 2f9cba0c Stefan Weil
                            mm_period,          /* resolution */
704 2f9cba0c Stefan Weil
                            mm_alarm_handler,   /* function */
705 2f9cba0c Stefan Weil
                            (DWORD_PTR)t,       /* parameter */
706 2f9cba0c Stefan Weil
                            flags);
707 2f9cba0c Stefan Weil
708 2f9cba0c Stefan Weil
    if (!mm_timer) {
709 2f9cba0c Stefan Weil
        fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
710 2f9cba0c Stefan Weil
                GetLastError());
711 2f9cba0c Stefan Weil
        timeEndPeriod(mm_period);
712 2f9cba0c Stefan Weil
        return -1;
713 2f9cba0c Stefan Weil
    }
714 2f9cba0c Stefan Weil
715 2f9cba0c Stefan Weil
    return 0;
716 2f9cba0c Stefan Weil
}
717 2f9cba0c Stefan Weil
718 2f9cba0c Stefan Weil
static void mm_stop_timer(struct qemu_alarm_timer *t)
719 2f9cba0c Stefan Weil
{
720 2f9cba0c Stefan Weil
    timeKillEvent(mm_timer);
721 2f9cba0c Stefan Weil
    timeEndPeriod(mm_period);
722 2f9cba0c Stefan Weil
}
723 2f9cba0c Stefan Weil
724 f3fc6e2e Paolo Bonzini
static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta)
725 2f9cba0c Stefan Weil
{
726 f3fc6e2e Paolo Bonzini
    int nearest_delta_ms = (delta + 999999) / 1000000;
727 2f9cba0c Stefan Weil
    if (nearest_delta_ms < 1) {
728 2f9cba0c Stefan Weil
        nearest_delta_ms = 1;
729 2f9cba0c Stefan Weil
    }
730 f3fc6e2e Paolo Bonzini
731 f3fc6e2e Paolo Bonzini
    timeKillEvent(mm_timer);
732 2f9cba0c Stefan Weil
    mm_timer = timeSetEvent(nearest_delta_ms,
733 2f9cba0c Stefan Weil
                            mm_period,
734 2f9cba0c Stefan Weil
                            mm_alarm_handler,
735 2f9cba0c Stefan Weil
                            (DWORD_PTR)t,
736 2f9cba0c Stefan Weil
                            TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
737 2f9cba0c Stefan Weil
738 2f9cba0c Stefan Weil
    if (!mm_timer) {
739 2f9cba0c Stefan Weil
        fprintf(stderr, "Failed to re-arm win32 alarm timer %ld\n",
740 2f9cba0c Stefan Weil
                GetLastError());
741 2f9cba0c Stefan Weil
742 2f9cba0c Stefan Weil
        timeEndPeriod(mm_period);
743 2f9cba0c Stefan Weil
        exit(1);
744 2f9cba0c Stefan Weil
    }
745 2f9cba0c Stefan Weil
}
746 2f9cba0c Stefan Weil
747 db1a4972 Paolo Bonzini
static int win32_start_timer(struct qemu_alarm_timer *t)
748 db1a4972 Paolo Bonzini
{
749 68c23e55 Paolo Bonzini
    HANDLE hTimer;
750 68c23e55 Paolo Bonzini
    BOOLEAN success;
751 68c23e55 Paolo Bonzini
752 68c23e55 Paolo Bonzini
    /* If you call ChangeTimerQueueTimer on a one-shot timer (its period
753 68c23e55 Paolo Bonzini
       is zero) that has already expired, the timer is not updated.  Since
754 68c23e55 Paolo Bonzini
       creating a new timer is relatively expensive, set a bogus one-hour
755 68c23e55 Paolo Bonzini
       interval in the dynticks case.  */
756 68c23e55 Paolo Bonzini
    success = CreateTimerQueueTimer(&hTimer,
757 68c23e55 Paolo Bonzini
                          NULL,
758 68c23e55 Paolo Bonzini
                          host_alarm_handler,
759 68c23e55 Paolo Bonzini
                          t,
760 68c23e55 Paolo Bonzini
                          1,
761 68c23e55 Paolo Bonzini
                          alarm_has_dynticks(t) ? 3600000 : 1,
762 68c23e55 Paolo Bonzini
                          WT_EXECUTEINTIMERTHREAD);
763 68c23e55 Paolo Bonzini
764 68c23e55 Paolo Bonzini
    if (!success) {
765 db1a4972 Paolo Bonzini
        fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
766 db1a4972 Paolo Bonzini
                GetLastError());
767 db1a4972 Paolo Bonzini
        return -1;
768 db1a4972 Paolo Bonzini
    }
769 db1a4972 Paolo Bonzini
770 cd0544ee Stefan Weil
    t->timer = hTimer;
771 db1a4972 Paolo Bonzini
    return 0;
772 db1a4972 Paolo Bonzini
}
773 db1a4972 Paolo Bonzini
774 db1a4972 Paolo Bonzini
static void win32_stop_timer(struct qemu_alarm_timer *t)
775 db1a4972 Paolo Bonzini
{
776 cd0544ee Stefan Weil
    HANDLE hTimer = t->timer;
777 db1a4972 Paolo Bonzini
778 68c23e55 Paolo Bonzini
    if (hTimer) {
779 68c23e55 Paolo Bonzini
        DeleteTimerQueueTimer(NULL, hTimer, NULL);
780 68c23e55 Paolo Bonzini
    }
781 db1a4972 Paolo Bonzini
}
782 db1a4972 Paolo Bonzini
783 f3fc6e2e Paolo Bonzini
static void win32_rearm_timer(struct qemu_alarm_timer *t,
784 f3fc6e2e Paolo Bonzini
                              int64_t nearest_delta_ns)
785 db1a4972 Paolo Bonzini
{
786 cd0544ee Stefan Weil
    HANDLE hTimer = t->timer;
787 cfced5b2 Paolo Bonzini
    int nearest_delta_ms;
788 68c23e55 Paolo Bonzini
    BOOLEAN success;
789 db1a4972 Paolo Bonzini
790 f3fc6e2e Paolo Bonzini
    nearest_delta_ms = (nearest_delta_ns + 999999) / 1000000;
791 cfced5b2 Paolo Bonzini
    if (nearest_delta_ms < 1) {
792 cfced5b2 Paolo Bonzini
        nearest_delta_ms = 1;
793 cfced5b2 Paolo Bonzini
    }
794 68c23e55 Paolo Bonzini
    success = ChangeTimerQueueTimer(NULL,
795 68c23e55 Paolo Bonzini
                                    hTimer,
796 68c23e55 Paolo Bonzini
                                    nearest_delta_ms,
797 68c23e55 Paolo Bonzini
                                    3600000);
798 db1a4972 Paolo Bonzini
799 68c23e55 Paolo Bonzini
    if (!success) {
800 68c23e55 Paolo Bonzini
        fprintf(stderr, "Failed to rearm win32 alarm timer: %ld\n",
801 68c23e55 Paolo Bonzini
                GetLastError());
802 68c23e55 Paolo Bonzini
        exit(-1);
803 db1a4972 Paolo Bonzini
    }
804 68c23e55 Paolo Bonzini
805 db1a4972 Paolo Bonzini
}
806 db1a4972 Paolo Bonzini
807 db1a4972 Paolo Bonzini
#endif /* _WIN32 */
808 db1a4972 Paolo Bonzini
809 1dfb4dd9 Luiz Capitulino
static void alarm_timer_on_change_state_rearm(void *opaque, int running,
810 1dfb4dd9 Luiz Capitulino
                                              RunState state)
811 db1a4972 Paolo Bonzini
{
812 db1a4972 Paolo Bonzini
    if (running)
813 db1a4972 Paolo Bonzini
        qemu_rearm_alarm_timer((struct qemu_alarm_timer *) opaque);
814 db1a4972 Paolo Bonzini
}
815 db1a4972 Paolo Bonzini
816 4260a739 Paolo Bonzini
static void quit_timers(void)
817 4260a739 Paolo Bonzini
{
818 4260a739 Paolo Bonzini
    struct qemu_alarm_timer *t = alarm_timer;
819 4260a739 Paolo Bonzini
    alarm_timer = NULL;
820 4260a739 Paolo Bonzini
    t->stop(t);
821 4260a739 Paolo Bonzini
}
822 4260a739 Paolo Bonzini
823 db1a4972 Paolo Bonzini
int init_timer_alarm(void)
824 db1a4972 Paolo Bonzini
{
825 db1a4972 Paolo Bonzini
    struct qemu_alarm_timer *t = NULL;
826 db1a4972 Paolo Bonzini
    int i, err = -1;
827 db1a4972 Paolo Bonzini
828 db1a4972 Paolo Bonzini
    for (i = 0; alarm_timers[i].name; i++) {
829 db1a4972 Paolo Bonzini
        t = &alarm_timers[i];
830 db1a4972 Paolo Bonzini
831 db1a4972 Paolo Bonzini
        err = t->start(t);
832 db1a4972 Paolo Bonzini
        if (!err)
833 db1a4972 Paolo Bonzini
            break;
834 db1a4972 Paolo Bonzini
    }
835 db1a4972 Paolo Bonzini
836 db1a4972 Paolo Bonzini
    if (err) {
837 db1a4972 Paolo Bonzini
        err = -ENOENT;
838 db1a4972 Paolo Bonzini
        goto fail;
839 db1a4972 Paolo Bonzini
    }
840 db1a4972 Paolo Bonzini
841 db1a4972 Paolo Bonzini
    /* first event is at time 0 */
842 4260a739 Paolo Bonzini
    atexit(quit_timers);
843 db1a4972 Paolo Bonzini
    t->pending = 1;
844 db1a4972 Paolo Bonzini
    alarm_timer = t;
845 db1a4972 Paolo Bonzini
    qemu_add_vm_change_state_handler(alarm_timer_on_change_state_rearm, t);
846 db1a4972 Paolo Bonzini
847 db1a4972 Paolo Bonzini
    return 0;
848 db1a4972 Paolo Bonzini
849 db1a4972 Paolo Bonzini
fail:
850 db1a4972 Paolo Bonzini
    return err;
851 db1a4972 Paolo Bonzini
}
852 db1a4972 Paolo Bonzini
853 db1a4972 Paolo Bonzini
int qemu_calculate_timeout(void)
854 db1a4972 Paolo Bonzini
{
855 1ece93a9 Paolo Bonzini
    return 1000;
856 db1a4972 Paolo Bonzini
}