qemu-timer.c revision 34c48ff1e3ad5cd2084ca40188754d45f423750b
16a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/*
26a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * QEMU System Emulator
36a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner *
46a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * Copyright (c) 2003-2008 Fabrice Bellard
56a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner *
66a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * Permission is hereby granted, free of charge, to any person obtaining a copy
76a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * of this software and associated documentation files (the "Software"), to deal
86a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * in the Software without restriction, including without limitation the rights
96a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
106a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * copies of the Software, and to permit persons to whom the Software is
116a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * furnished to do so, subject to the following conditions:
126a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner *
136a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * The above copyright notice and this permission notice shall be included in
146a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * all copies or substantial portions of the Software.
156a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner *
166a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
176a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
186a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
196a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
206a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
216a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
226a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * THE SOFTWARE.
236a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner */
246a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
2534c48ff1e3ad5cd2084ca40188754d45f423750bDavid 'Digit' Turner#include "sysemu/sysemu.h"
26cc330d4169441727fecf1da08aee806fc021c4e2David 'Digit' Turner#include "net/net.h"
276af6765e2f3bc930d0dce21d752bea570a1b1362David 'Digit' Turner#include "monitor/monitor.h"
281c31e3e43ce4cca85a707dfff631e5e102fdecedDavid 'Digit' Turner#include "ui/console.h"
296a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
306a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include "hw/hw.h"
316a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
326a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include <unistd.h>
336a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include <fcntl.h>
346a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include <time.h>
356a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include <errno.h>
366a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include <sys/time.h>
376a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include <signal.h>
386a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#ifdef __FreeBSD__
396a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include <sys/param.h>
406a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif
416a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
426a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#ifdef __linux__
436a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include <sys/ioctl.h>
446a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include <linux/rtc.h>
456a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* For the benefit of older linux systems which don't supply it,
466a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner   we use a local copy of hpet.h. */
476a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* #include <linux/hpet.h> */
486a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include "hpet.h"
496a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif
506a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
516a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#ifdef _WIN32
526a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include <windows.h>
536a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include <mmsystem.h>
546a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif
556a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
567a78db75ad42aea283f5073f51891464104a9fc3David 'Digit' Turner#include "qemu/timer.h"
576a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
586a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* Conversion factor from emulated instructions to virtual clock ticks.  */
596a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerint icount_time_shift;
606a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* Arbitrarily pick 1MIPS as the minimum allowable speed.  */
616a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#define MAX_ICOUNT_SHIFT 10
626a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* Compensate for varying guest execution speed.  */
636a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerint64_t qemu_icount_bias;
646a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic QEMUTimer *icount_rt_timer;
656a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic QEMUTimer *icount_vm_timer;
666a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
676a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/***********************************************************/
686a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* guest cycle counter */
696a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
706a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnertypedef struct TimersState {
716a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    int64_t cpu_ticks_prev;
726a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    int64_t cpu_ticks_offset;
736a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    int64_t cpu_clock_offset;
746a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    int32_t cpu_ticks_enabled;
756a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    int64_t dummy;
766a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} TimersState;
776a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
786a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void timer_save(QEMUFile *f, void *opaque)
796a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
806a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    TimersState *s = opaque;
816a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
826a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (s->cpu_ticks_enabled) {
836a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        hw_error("cannot save state if virtual timers are running");
846a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
856a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    qemu_put_be64(f, s->cpu_ticks_prev);
866a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    qemu_put_be64(f, s->cpu_ticks_offset);
876a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    qemu_put_be64(f, s->cpu_clock_offset);
886a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner }
896a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
906a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int timer_load(QEMUFile *f, void *opaque, int version_id)
916a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
926a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    TimersState *s = opaque;
936a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
946a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (version_id != 1 && version_id != 2)
956a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return -EINVAL;
966a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (s->cpu_ticks_enabled) {
976a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return -EINVAL;
986a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
996a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    s->cpu_ticks_prev   = qemu_get_sbe64(f);
1006a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    s->cpu_ticks_offset = qemu_get_sbe64(f);
1016a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (version_id == 2) {
1026a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        s->cpu_clock_offset = qemu_get_sbe64(f);
1036a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
1046a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    return 0;
1056a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
1066a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
1076a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
1086a9ef1773bf874dea493ff3861782a1e577b67ddDavid TurnerTimersState timers_state;
1096a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
1106a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* return the host CPU cycle counter and handle stop/restart */
1116a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerint64_t cpu_get_ticks(void)
1126a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
1136a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (use_icount) {
1146a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return cpu_get_icount();
1156a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
1166a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (!timers_state.cpu_ticks_enabled) {
1176a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return timers_state.cpu_ticks_offset;
1186a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    } else {
1196a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        int64_t ticks;
1206a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        ticks = cpu_get_real_ticks();
1216a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        if (timers_state.cpu_ticks_prev > ticks) {
1226a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            /* Note: non increasing ticks may happen if the host uses
1236a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner               software suspend */
1246a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            timers_state.cpu_ticks_offset += timers_state.cpu_ticks_prev - ticks;
1256a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        }
1266a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        timers_state.cpu_ticks_prev = ticks;
1276a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return ticks + timers_state.cpu_ticks_offset;
1286a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
1296a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
1306a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
1316a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* return the host CPU monotonic timer and handle stop/restart */
1326a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int64_t cpu_get_clock(void)
1336a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
1346a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    int64_t ti;
1356a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (!timers_state.cpu_ticks_enabled) {
1366a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return timers_state.cpu_clock_offset;
1376a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    } else {
1386a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        ti = get_clock();
1396a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return ti + timers_state.cpu_clock_offset;
1406a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
1416a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
1426a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
1436a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#ifndef CONFIG_IOTHREAD
1446a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int64_t qemu_icount_delta(void)
1456a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
1466a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (!use_icount) {
1476a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return 5000 * (int64_t) 1000000;
1486a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    } else if (use_icount == 1) {
1496a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        /* When not using an adaptive execution frequency
1506a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner           we tend to get badly out of sync with real time,
1516a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner           so just delay for a reasonable amount of time.  */
1526a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return 0;
1536a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    } else {
1546a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return cpu_get_icount() - cpu_get_clock();
1556a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
1566a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
1576a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif
1586a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
1596a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* enable cpu_get_ticks() */
1606a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnervoid cpu_enable_ticks(void)
1616a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
1626a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (!timers_state.cpu_ticks_enabled) {
1636a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        timers_state.cpu_ticks_offset -= cpu_get_real_ticks();
1646a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        timers_state.cpu_clock_offset -= get_clock();
1656a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        timers_state.cpu_ticks_enabled = 1;
1666a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
1676a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
1686a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
1696a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* disable cpu_get_ticks() : the clock is stopped. You must not call
1706a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner   cpu_get_ticks() after that.  */
1716a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnervoid cpu_disable_ticks(void)
1726a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
1736a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (timers_state.cpu_ticks_enabled) {
1746a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        timers_state.cpu_ticks_offset = cpu_get_ticks();
1756a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        timers_state.cpu_clock_offset = cpu_get_clock();
1766a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        timers_state.cpu_ticks_enabled = 0;
1776a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
1786a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
1796a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
1806a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/***********************************************************/
1816a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* timers */
1826a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
1836a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#define QEMU_CLOCK_REALTIME 0
1846a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#define QEMU_CLOCK_VIRTUAL  1
1856a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#define QEMU_CLOCK_HOST     2
1866a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
1876a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstruct QEMUClock {
1886a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    int type;
1896a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    int enabled;
190317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
191317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    QEMUTimer *warp_timer;
1926a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner};
1936a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
1946a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstruct QEMUTimer {
1956a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    QEMUClock *clock;
196317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    int64_t expire_time;	/* in nanoseconds */
197317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    int scale;
1986a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    QEMUTimerCB *cb;
1996a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    void *opaque;
2006a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    struct QEMUTimer *next;
2016a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner};
2026a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
2036a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstruct qemu_alarm_timer {
2046a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    char const *name;
2056a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    int (*start)(struct qemu_alarm_timer *t);
2066a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    void (*stop)(struct qemu_alarm_timer *t);
2076a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    void (*rearm)(struct qemu_alarm_timer *t);
208317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner#if defined(__linux__)
209317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    int fd;
210317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    timer_t timer;
211317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner#elif defined(_WIN32)
212317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    HANDLE timer;
213317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner#endif
2146a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    char expired;
2156a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    char pending;
2166a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner};
2176a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
2186a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic struct qemu_alarm_timer *alarm_timer;
2196a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
220317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turnerstatic bool qemu_timer_expired_ns(QEMUTimer *timer_head, int64_t current_time)
221317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner{
222317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    return timer_head && (timer_head->expire_time <= current_time);
223317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner}
224317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
2256a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerint qemu_alarm_pending(void)
2266a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
2276a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    return alarm_timer->pending;
2286a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
2296a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
2306a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic inline int alarm_has_dynticks(struct qemu_alarm_timer *t)
2316a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
2326a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    return !!t->rearm;
2336a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
2346a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
2356a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
2366a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
2376a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (!alarm_has_dynticks(t))
2386a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return;
2396a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
2406a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    t->rearm(t);
2416a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
2426a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
243317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner/* TODO: MIN_TIMER_REARM_NS should be optimized */
244317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner#define MIN_TIMER_REARM_NS 250000
2456a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
2466a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#ifdef _WIN32
2476a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
248317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turnerstatic int mm_start_timer(struct qemu_alarm_timer *t);
249317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turnerstatic void mm_stop_timer(struct qemu_alarm_timer *t);
250317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turnerstatic void mm_rearm_timer(struct qemu_alarm_timer *t);
2516a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
2526a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int win32_start_timer(struct qemu_alarm_timer *t);
2536a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void win32_stop_timer(struct qemu_alarm_timer *t);
2546a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void win32_rearm_timer(struct qemu_alarm_timer *t);
2556a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
2566a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#else
2576a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
2586a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int unix_start_timer(struct qemu_alarm_timer *t);
2596a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void unix_stop_timer(struct qemu_alarm_timer *t);
2606a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
2616a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#ifdef __linux__
2626a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
2636a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int dynticks_start_timer(struct qemu_alarm_timer *t);
2646a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void dynticks_stop_timer(struct qemu_alarm_timer *t);
2656a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void dynticks_rearm_timer(struct qemu_alarm_timer *t);
2666a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
2676a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int hpet_start_timer(struct qemu_alarm_timer *t);
2686a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void hpet_stop_timer(struct qemu_alarm_timer *t);
2696a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
2706a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int rtc_start_timer(struct qemu_alarm_timer *t);
2716a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void rtc_stop_timer(struct qemu_alarm_timer *t);
2726a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
2736a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif /* __linux__ */
2746a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
2756a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif /* _WIN32 */
2766a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
2776a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* Correlation between real and virtual time is always going to be
2786a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner   fairly approximate, so ignore small variation.
2796a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner   When the guest is idle real and virtual time will be aligned in
2806a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner   the IO wait loop.  */
2816a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#define ICOUNT_WOBBLE (get_ticks_per_sec() / 10)
2826a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
2836a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void icount_adjust(void)
2846a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
2856a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    int64_t cur_time;
2866a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    int64_t cur_icount;
2876a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    int64_t delta;
2886a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    static int64_t last_delta;
2896a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    /* If the VM is not running, then do nothing.  */
2906a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (!vm_running)
2916a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return;
2926a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
2936a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    cur_time = cpu_get_clock();
294317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    cur_icount = qemu_get_clock_ns(vm_clock);
2956a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    delta = cur_icount - cur_time;
2966a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    /* FIXME: This is a very crude algorithm, somewhat prone to oscillation.  */
2976a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (delta > 0
2986a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        && last_delta + ICOUNT_WOBBLE < delta * 2
2996a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        && icount_time_shift > 0) {
3006a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        /* The guest is getting too far ahead.  Slow time down.  */
3016a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        icount_time_shift--;
3026a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
3036a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (delta < 0
3046a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        && last_delta - ICOUNT_WOBBLE > delta * 2
3056a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        && icount_time_shift < MAX_ICOUNT_SHIFT) {
3066a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        /* The guest is getting too far behind.  Speed time up.  */
3076a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        icount_time_shift++;
3086a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
3096a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    last_delta = delta;
3106a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    qemu_icount_bias = cur_icount - (qemu_icount << icount_time_shift);
3116a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
3126a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
3136a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void icount_adjust_rt(void * opaque)
3146a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
3156a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    qemu_mod_timer(icount_rt_timer,
316317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                   qemu_get_clock_ms(rt_clock) + 1000);
3176a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    icount_adjust();
3186a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
3196a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
3206a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void icount_adjust_vm(void * opaque)
3216a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
3226a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    qemu_mod_timer(icount_vm_timer,
323317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                   qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 10);
3246a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    icount_adjust();
3256a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
3266a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
3276a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerint64_t qemu_icount_round(int64_t count)
3286a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
3296a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    return (count + (1 << icount_time_shift) - 1) >> icount_time_shift;
3306a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
3316a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
3326a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic struct qemu_alarm_timer alarm_timers[] = {
3336a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#ifndef _WIN32
3346a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#ifdef __linux__
3356a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    /* HPET - if available - is preferred */
336317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    {"hpet", hpet_start_timer, hpet_stop_timer, NULL},
3376a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    /* ...otherwise try RTC */
338317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    {"rtc", rtc_start_timer, rtc_stop_timer, NULL},
3396a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif
340317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    {"unix", unix_start_timer, unix_stop_timer, NULL},
341d543578f5d2e900ca9a95befaf15d49da163d5fbDavid 'Digit' Turner#ifdef __linux__
342d543578f5d2e900ca9a95befaf15d49da163d5fbDavid 'Digit' Turner    /* on Linux, the 'dynticks' clock sometimes doesn't work
343d543578f5d2e900ca9a95befaf15d49da163d5fbDavid 'Digit' Turner     * properly. this results in the UI freezing while emulation
344d543578f5d2e900ca9a95befaf15d49da163d5fbDavid 'Digit' Turner     * continues, for several seconds... So move it to the end
345d543578f5d2e900ca9a95befaf15d49da163d5fbDavid 'Digit' Turner     * of the list. */
346d543578f5d2e900ca9a95befaf15d49da163d5fbDavid 'Digit' Turner    {"dynticks", dynticks_start_timer,
347317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner     dynticks_stop_timer, dynticks_rearm_timer},
348d543578f5d2e900ca9a95befaf15d49da163d5fbDavid 'Digit' Turner#endif
3496a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#else
350317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    {"mmtimer", mm_start_timer, mm_stop_timer, NULL},
351317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    {"mmtimer2", mm_start_timer, mm_stop_timer, mm_rearm_timer},
352317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    {"dynticks", win32_start_timer, win32_stop_timer, win32_rearm_timer},
353317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    {"win32", win32_start_timer, win32_stop_timer, NULL},
3546a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif
3556a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    {NULL, }
3566a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner};
3576a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
3586a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void show_available_alarms(void)
3596a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
3606a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    int i;
3616a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
3626a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    printf("Available alarm timers, in order of precedence:\n");
3636a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    for (i = 0; alarm_timers[i].name; i++)
3646a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        printf("%s\n", alarm_timers[i].name);
3656a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
3666a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
3676a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnervoid configure_alarms(char const *opt)
3686a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
3696a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    int i;
3706a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    int cur = 0;
3716a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    int count = ARRAY_SIZE(alarm_timers) - 1;
3726a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    char *arg;
3736a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    char *name;
3746a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    struct qemu_alarm_timer tmp;
3756a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
3766a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (!strcmp(opt, "?")) {
3776a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        show_available_alarms();
3786a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        exit(0);
3796a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
3806a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
3816a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    arg = qemu_strdup(opt);
3826a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
3836a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    /* Reorder the array */
3846a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    name = strtok(arg, ",");
3856a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    while (name) {
3866a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        for (i = 0; i < count && alarm_timers[i].name; i++) {
3876a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            if (!strcmp(alarm_timers[i].name, name))
3886a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner                break;
3896a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        }
3906a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
3916a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        if (i == count) {
3926a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            fprintf(stderr, "Unknown clock %s\n", name);
3936a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            goto next;
3946a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        }
3956a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
3966a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        if (i < cur)
3976a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            /* Ignore */
3986a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            goto next;
3996a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
4006a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner	/* Swap */
4016a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        tmp = alarm_timers[i];
4026a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        alarm_timers[i] = alarm_timers[cur];
4036a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        alarm_timers[cur] = tmp;
4046a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
4056a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        cur++;
4066a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnernext:
4076a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        name = strtok(NULL, ",");
4086a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
4096a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
4106a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    qemu_free(arg);
4116a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
4126a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (cur) {
4136a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        /* Disable remaining timers */
4146a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        for (i = cur; i < count; i++)
4156a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            alarm_timers[i].name = NULL;
4166a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    } else {
4176a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        show_available_alarms();
4186a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        exit(1);
4196a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
4206a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
4216a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
4226a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#define QEMU_NUM_CLOCKS 3
4236a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
4246a9ef1773bf874dea493ff3861782a1e577b67ddDavid TurnerQEMUClock *rt_clock;
4256a9ef1773bf874dea493ff3861782a1e577b67ddDavid TurnerQEMUClock *vm_clock;
4266a9ef1773bf874dea493ff3861782a1e577b67ddDavid TurnerQEMUClock *host_clock;
4276a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
4286a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic QEMUTimer *active_timers[QEMU_NUM_CLOCKS];
4296a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
4306a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic QEMUClock *qemu_new_clock(int type)
4316a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
4326a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    QEMUClock *clock;
4336a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    clock = qemu_mallocz(sizeof(QEMUClock));
4346a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    clock->type = type;
4356a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    clock->enabled = 1;
4366a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    return clock;
4376a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
4386a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
4396a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnervoid qemu_clock_enable(QEMUClock *clock, int enabled)
4406a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
4416a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    clock->enabled = enabled;
4426a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
4436a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
444317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turnerstatic int64_t vm_clock_warp_start;
445317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
446317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turnerstatic void icount_warp_rt(void *opaque)
447317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner{
448317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    if (vm_clock_warp_start == -1) {
449317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        return;
450317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    }
451317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
452317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    if (vm_running) {
453317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        int64_t clock = qemu_get_clock_ns(rt_clock);
454317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        int64_t warp_delta = clock - vm_clock_warp_start;
455317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        if (use_icount == 1) {
456317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner            qemu_icount_bias += warp_delta;
457317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        } else {
458317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner            /*
459317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner             * In adaptive mode, do not let the vm_clock run too
460317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner             * far ahead of real time.
461317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner             */
462317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner            int64_t cur_time = cpu_get_clock();
463317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner            int64_t cur_icount = qemu_get_clock_ns(vm_clock);
464317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner            int64_t delta = cur_time - cur_icount;
465317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner            qemu_icount_bias += MIN(warp_delta, delta);
466317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        }
467317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        if (qemu_timer_expired(active_timers[QEMU_CLOCK_VIRTUAL],
468317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                               qemu_get_clock_ns(vm_clock))) {
469317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner            qemu_notify_event();
470317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        }
471317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    }
472317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    vm_clock_warp_start = -1;
473317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner}
474317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
475317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turnervoid qemu_clock_warp(QEMUClock *clock)
476317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner{
477317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    int64_t deadline;
478317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
479317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    if (!clock->warp_timer) {
480317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        return;
481317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    }
482317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
483317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    /*
484317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner     * There are too many global variables to make the "warp" behavior
485317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner     * applicable to other clocks.  But a clock argument removes the
486317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner     * need for if statements all over the place.
487317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner     */
488317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    assert(clock == vm_clock);
489317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
490317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    /*
491317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner     * If the CPUs have been sleeping, advance the vm_clock timer now.  This
492317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner     * ensures that the deadline for the timer is computed correctly below.
493317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner     * This also makes sure that the insn counter is synchronized before the
494317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner     * CPU starts running, in case the CPU is woken by an event other than
495317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner     * the earliest vm_clock timer.
496317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner     */
497317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    icount_warp_rt(NULL);
498317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    if (qemu_cpu_has_work(cpu_single_env) || !active_timers[clock->type]) {
499317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        qemu_del_timer(clock->warp_timer);
500317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        return;
501317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    }
502317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
503317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    vm_clock_warp_start = qemu_get_clock_ns(rt_clock);
504317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    deadline = qemu_next_icount_deadline();
505317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    if (deadline > 0) {
506317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        /*
507317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner         * Ensure the vm_clock proceeds even when the virtual CPU goes to
508317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner         * sleep.  Otherwise, the CPU might be waiting for a future timer
509317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner         * interrupt to wake it up, but the interrupt never comes because
510317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner         * the vCPU isn't running any insns and thus doesn't advance the
511317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner         * vm_clock.
512317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner         *
513317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner         * An extreme solution for this problem would be to never let VCPUs
514317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner         * sleep in icount mode if there is a pending vm_clock timer; rather
515317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner         * time could just advance to the next vm_clock event.  Instead, we
516317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner         * do stop VCPUs and only advance vm_clock after some "real" time,
517317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner         * (related to the time left until the next event) has passed.  This
518317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner         * rt_clock timer will do this.  This avoids that the warps are too
519317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner         * visible externally---for example, you will not be sending network
520317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner         * packets continously instead of every 100ms.
521317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner         */
522317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        qemu_mod_timer(clock->warp_timer, vm_clock_warp_start + deadline);
523317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    } else {
524317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        qemu_notify_event();
525317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    }
526317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner}
527317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
5285973c775c853e26f684de58ad28c267281aaffd6David 'Digit' TurnerQEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
529317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                          QEMUTimerCB *cb, void *opaque)
5306a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
5316a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    QEMUTimer *ts;
5326a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
5336a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    ts = qemu_mallocz(sizeof(QEMUTimer));
5346a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    ts->clock = clock;
5356a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    ts->cb = cb;
5366a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    ts->opaque = opaque;
537317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    ts->scale = scale;
5386a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    return ts;
5396a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
5406a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
5416a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnervoid qemu_free_timer(QEMUTimer *ts)
5426a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
5436a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    qemu_free(ts);
5446a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
5456a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
5466a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* stop a timer, but do not dealloc it */
5476a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnervoid qemu_del_timer(QEMUTimer *ts)
5486a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
5496a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    QEMUTimer **pt, *t;
5506a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
5516a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    /* NOTE: this code must be signal safe because
5526a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner       qemu_timer_expired() can be called from a signal. */
5536a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    pt = &active_timers[ts->clock->type];
5546a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    for(;;) {
5556a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        t = *pt;
5566a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        if (!t)
5576a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            break;
5586a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        if (t == ts) {
5596a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            *pt = t->next;
5606a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            break;
5616a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        }
5626a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        pt = &t->next;
5636a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
5646a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
5656a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
5666a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* modify the current timer so that it will be fired when current_time
5676a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner   >= expire_time. The corresponding callback will be called. */
568317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turnerstatic void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)
5696a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
5706a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    QEMUTimer **pt, *t;
5716a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
5726a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    qemu_del_timer(ts);
5736a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
5746a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    /* add the timer in the sorted list */
5756a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    /* NOTE: this code must be signal safe because
5766a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner       qemu_timer_expired() can be called from a signal. */
5776a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    pt = &active_timers[ts->clock->type];
5786a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    for(;;) {
5796a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        t = *pt;
580317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        if (!qemu_timer_expired_ns(t, expire_time)) {
5816a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            break;
582317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        }
5836a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        pt = &t->next;
5846a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
5856a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    ts->expire_time = expire_time;
5866a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    ts->next = *pt;
5876a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    *pt = ts;
5886a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
5896a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    /* Rearm if necessary  */
5906a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (pt == &active_timers[ts->clock->type]) {
5916a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        if (!alarm_timer->pending) {
5926a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            qemu_rearm_alarm_timer(alarm_timer);
5936a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        }
5946a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        /* Interrupt execution to force deadline recalculation.  */
595317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        qemu_clock_warp(ts->clock);
596317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        if (use_icount) {
5976a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            qemu_notify_event();
5986a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
599317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    }
600317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner}
601317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
602317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner/* modify the current timer so that it will be fired when current_time
603317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner   >= expire_time. The corresponding callback will be called. */
604317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turnervoid qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
605317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner{
606317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    qemu_mod_timer_ns(ts, expire_time * ts->scale);
6076a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
6086a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
6096a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerint qemu_timer_pending(QEMUTimer *ts)
6106a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
6116a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    QEMUTimer *t;
6126a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    for(t = active_timers[ts->clock->type]; t != NULL; t = t->next) {
6136a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        if (t == ts)
6146a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            return 1;
6156a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
6166a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    return 0;
6176a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
6186a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
6196a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerint qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
6206a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
621317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    return qemu_timer_expired_ns(timer_head, current_time * timer_head->scale);
6226a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
6236a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
6246a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void qemu_run_timers(QEMUClock *clock)
6256a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
6266a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    QEMUTimer **ptimer_head, *ts;
6276a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    int64_t current_time;
6286b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner
6296a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (!clock->enabled)
6306a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return;
6316a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
632317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    current_time = qemu_get_clock_ns(clock);
6336a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    ptimer_head = &active_timers[clock->type];
6346a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    for(;;) {
6356a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        ts = *ptimer_head;
636317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        if (!qemu_timer_expired_ns(ts, current_time)) {
6376a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            break;
638317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        }
6396a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        /* remove timer from the list before calling the callback */
6406a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        *ptimer_head = ts->next;
6416a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        ts->next = NULL;
6426a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
6436a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        /* run the callback (the timer list can be modified) */
6446a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        ts->cb(ts->opaque);
6456a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
6466a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
6476a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
6486a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerint64_t qemu_get_clock(QEMUClock *clock)
6496a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
6506a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    switch(clock->type) {
6516a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    case QEMU_CLOCK_REALTIME:
6526a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return get_clock() / 1000000;
6536a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    default:
6546a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    case QEMU_CLOCK_VIRTUAL:
6556a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        if (use_icount) {
6566a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            return cpu_get_icount();
6576a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        } else {
6586a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            return cpu_get_clock();
6596a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        }
6606a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    case QEMU_CLOCK_HOST:
6616a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return get_clock_realtime();
6626a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
6636a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
6646a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
6656a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerint64_t qemu_get_clock_ns(QEMUClock *clock)
6666a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
6676a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    switch(clock->type) {
6686a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    case QEMU_CLOCK_REALTIME:
6696a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return get_clock();
6706a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    default:
6716a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    case QEMU_CLOCK_VIRTUAL:
6726a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        if (use_icount) {
6736a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            return cpu_get_icount();
6746a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        } else {
6756a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            return cpu_get_clock();
6766a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        }
6776a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    case QEMU_CLOCK_HOST:
6786a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return get_clock_realtime();
6796a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
6806a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
6816a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
6826a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnervoid init_clocks(void)
6836a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
6846a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    rt_clock = qemu_new_clock(QEMU_CLOCK_REALTIME);
6856a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    vm_clock = qemu_new_clock(QEMU_CLOCK_VIRTUAL);
6866a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    host_clock = qemu_new_clock(QEMU_CLOCK_HOST);
6876a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
6886a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    rtc_clock = host_clock;
6896a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
6906a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
6916a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* save a timer */
6926a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnervoid qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
6936a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
6946a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    uint64_t expire_time;
6956a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
6966a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (qemu_timer_pending(ts)) {
6976a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        expire_time = ts->expire_time;
6986a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    } else {
6996a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        expire_time = -1;
7006a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
7016a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    qemu_put_be64(f, expire_time);
7026a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
7036a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
7046a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnervoid qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
7056a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
7066a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    uint64_t expire_time;
7076a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
7086a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    expire_time = qemu_get_be64(f);
7096a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (expire_time != -1) {
710317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        qemu_mod_timer_ns(ts, expire_time);
7116a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    } else {
7126a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        qemu_del_timer(ts);
7136a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
7146a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
7156a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
7166a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#if 0
7176a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic const VMStateDescription vmstate_timers = {
7186a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    .name = "timer",
7196a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    .version_id = 2,
7206a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    .minimum_version_id = 1,
7216a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    .minimum_version_id_old = 1,
7226a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    .fields      = (VMStateField []) {
7236a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        VMSTATE_INT64(cpu_ticks_offset, TimersState),
7246a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        VMSTATE_INT64(dummy, TimersState),
7256a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        VMSTATE_INT64_V(cpu_clock_offset, TimersState, 2),
7266a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        VMSTATE_END_OF_LIST()
7276a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
7286a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner};
7296a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif
7306a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
7316a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnervoid configure_icount(const char *option)
7326a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
7331091d5d16923c044d35fcacfe845ab6b76e83143Ot ten Thije    register_savevm("timer", 0, 2, timer_save, timer_load, &timers_state);
7346a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
7356a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (!option)
7366a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return;
7376a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
738317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner#ifdef CONFIG_IOTHREAD
739317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    vm_clock->warp_timer = qemu_new_timer_ns(rt_clock, icount_warp_rt, NULL);
740317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner#endif
741317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
7426a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (strcmp(option, "auto") != 0) {
7436a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        icount_time_shift = strtol(option, NULL, 0);
7446a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        use_icount = 1;
7456a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return;
7466a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
7476a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
7486a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    use_icount = 2;
7496a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
7506a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    /* 125MIPS seems a reasonable initial guess at the guest speed.
7516a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner       It will be corrected fairly quickly anyway.  */
7526a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    icount_time_shift = 3;
7536a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
7546a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    /* Have both realtime and virtual time triggers for speed adjustment.
7556a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner       The realtime trigger catches emulated time passing too slowly,
7566a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner       the virtual time trigger catches emulated time passing too fast.
7576a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner       Realtime triggers occur even when idle, so use them less frequently
7586a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner       than VM triggers.  */
759317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    icount_rt_timer = qemu_new_timer_ms(rt_clock, icount_adjust_rt, NULL);
7606a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    qemu_mod_timer(icount_rt_timer,
761317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                   qemu_get_clock_ms(rt_clock) + 1000);
762317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    icount_vm_timer = qemu_new_timer_ns(vm_clock, icount_adjust_vm, NULL);
7636a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    qemu_mod_timer(icount_vm_timer,
764317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                   qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 10);
7656a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
7666a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
7676a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnervoid qemu_run_all_timers(void)
7686a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
7696a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    alarm_timer->pending = 0;
7706a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
7716a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    /* rearm timer, if not periodic */
7726a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (alarm_timer->expired) {
7736a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        alarm_timer->expired = 0;
7746a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        qemu_rearm_alarm_timer(alarm_timer);
7756a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
7766a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
7776a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    /* vm time timers */
7786a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (vm_running) {
7796a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        qemu_run_timers(vm_clock);
7806a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
7816a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
7826a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    qemu_run_timers(rt_clock);
7836a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    qemu_run_timers(host_clock);
7846a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
7856a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
7866b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turnerstatic int timer_alarm_pending = 1;
7876b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner
7886b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turnerint qemu_timer_alarm_pending(void)
7896b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner{
7906b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner    int ret = timer_alarm_pending;
7916b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner    timer_alarm_pending = 0;
7926b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner    return ret;
7936b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner}
7946b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner
795317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
796317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turnerstatic int64_t qemu_next_alarm_deadline(void);
797317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
7986a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#ifdef _WIN32
799317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turnerstatic void CALLBACK host_alarm_handler(PVOID lpParam, BOOLEAN unused)
8006a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#else
8016a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void host_alarm_handler(int host_signum)
8026a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif
8036a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
8046a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    struct qemu_alarm_timer *t = alarm_timer;
8056a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (!t)
8066a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner	return;
8076a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
8086a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#if 0
8096a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#define DISP_FREQ 1000
8106a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    {
8116a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        static int64_t delta_min = INT64_MAX;
8126a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        static int64_t delta_max, delta_cum, last_clock, delta, ti;
8136a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        static int count;
814317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        ti = qemu_get_clock_ns(vm_clock);
8156a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        if (last_clock != 0) {
8166a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            delta = ti - last_clock;
8176a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            if (delta < delta_min)
8186a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner                delta_min = delta;
8196a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            if (delta > delta_max)
8206a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner                delta_max = delta;
8216a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            delta_cum += delta;
8226a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            if (++count == DISP_FREQ) {
8236a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner                printf("timer: min=%" PRId64 " us max=%" PRId64 " us avg=%" PRId64 " us avg_freq=%0.3f Hz\n",
8246a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner                       muldiv64(delta_min, 1000000, get_ticks_per_sec()),
8256a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner                       muldiv64(delta_max, 1000000, get_ticks_per_sec()),
8266a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner                       muldiv64(delta_cum, 1000000 / DISP_FREQ, get_ticks_per_sec()),
8276a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner                       (double)get_ticks_per_sec() / ((double)delta_cum / DISP_FREQ));
8286a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner                count = 0;
8296a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner                delta_min = INT64_MAX;
8306a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner                delta_max = 0;
8316a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner                delta_cum = 0;
8326a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            }
8336a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        }
8346a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        last_clock = ti;
8356a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
8366a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif
8376a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (alarm_has_dynticks(t) ||
838317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        qemu_next_alarm_deadline () <= 0) {
8396a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        t->expired = alarm_has_dynticks(t);
8406a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        t->pending = 1;
8416b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner        timer_alarm_pending = 1;
8426a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        qemu_notify_event();
8436a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
8446a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
8456a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
846317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turnerint64_t qemu_next_icount_deadline(void)
8476a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
8486a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    /* To avoid problems with overflow limit this to 2^32.  */
8496a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    int64_t delta = INT32_MAX;
8506a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
851317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    assert(use_icount);
8526a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (active_timers[QEMU_CLOCK_VIRTUAL]) {
8536a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        delta = active_timers[QEMU_CLOCK_VIRTUAL]->expire_time -
854317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                     qemu_get_clock_ns(vm_clock);
8556a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
8566a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
8576a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (delta < 0)
8586a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        delta = 0;
8596a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
8606a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    return delta;
8616a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
8626a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
863317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turnerstatic int64_t qemu_next_alarm_deadline(void)
8646a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
8656a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    int64_t delta;
8666a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    int64_t rtdelta;
8676a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
868317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    if (!use_icount && active_timers[QEMU_CLOCK_VIRTUAL]) {
869317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        delta = active_timers[QEMU_CLOCK_VIRTUAL]->expire_time -
870317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                     qemu_get_clock_ns(vm_clock);
871317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    } else {
8726a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        delta = INT32_MAX;
873317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    }
874317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    if (active_timers[QEMU_CLOCK_HOST]) {
875317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        int64_t hdelta = active_timers[QEMU_CLOCK_HOST]->expire_time -
876317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                 qemu_get_clock_ns(host_clock);
877317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        if (hdelta < delta)
878317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner            delta = hdelta;
879317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    }
8806a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (active_timers[QEMU_CLOCK_REALTIME]) {
8816a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        rtdelta = (active_timers[QEMU_CLOCK_REALTIME]->expire_time -
882317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                 qemu_get_clock_ns(rt_clock));
8836a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        if (rtdelta < delta)
8846a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            delta = rtdelta;
8856a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
8866a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
8876a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    return delta;
8886a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
8896a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
890317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner#if defined(__linux__)
891317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
892317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner#define RTC_FREQ 1024
893317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
8946a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void enable_sigio_timer(int fd)
8956a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
8966a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    struct sigaction act;
8976a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
8986a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    /* timer signal */
8996a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    sigfillset(&act.sa_mask);
9006a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    act.sa_flags = 0;
9016a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    act.sa_handler = host_alarm_handler;
9026a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
9036a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    sigaction(SIGIO, &act, NULL);
9046a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    fcntl_setfl(fd, O_ASYNC);
9056a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    fcntl(fd, F_SETOWN, getpid());
9066a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
9076a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
9086a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int hpet_start_timer(struct qemu_alarm_timer *t)
9096a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
9106a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    struct hpet_info info;
9116a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    int r, fd;
9126a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
9136a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    fd = open("/dev/hpet", O_RDONLY);
9146a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (fd < 0)
9156a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return -1;
9166a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
9176a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    /* Set frequency */
9186a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    r = ioctl(fd, HPET_IRQFREQ, RTC_FREQ);
9196a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (r < 0) {
9206a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        fprintf(stderr, "Could not configure '/dev/hpet' to have a 1024Hz timer. This is not a fatal\n"
9216a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner                "error, but for better emulation accuracy type:\n"
9226a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner                "'echo 1024 > /proc/sys/dev/hpet/max-user-freq' as root.\n");
9236a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        goto fail;
9246a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
9256a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
9266a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    /* Check capabilities */
9276a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    r = ioctl(fd, HPET_INFO, &info);
9286a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (r < 0)
9296a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        goto fail;
9306a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
9316a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    /* Enable periodic mode */
9326a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    r = ioctl(fd, HPET_EPI, 0);
9336a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (info.hi_flags && (r < 0))
9346a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        goto fail;
9356a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
9366a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    /* Enable interrupt */
9376a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    r = ioctl(fd, HPET_IE_ON, 0);
9386a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (r < 0)
9396a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        goto fail;
9406a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
9416a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    enable_sigio_timer(fd);
942317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    t->fd = fd;
9436a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
9446a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    return 0;
9456a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerfail:
9466a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    close(fd);
9476a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    return -1;
9486a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
9496a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
9506a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void hpet_stop_timer(struct qemu_alarm_timer *t)
9516a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
952317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    int fd = t->fd;
9536a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
9546a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    close(fd);
9556a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
9566a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
9576a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int rtc_start_timer(struct qemu_alarm_timer *t)
9586a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
9596a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    int rtc_fd;
9606a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    unsigned long current_rtc_freq = 0;
9616a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
9626a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    TFR(rtc_fd = open("/dev/rtc", O_RDONLY));
9636a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (rtc_fd < 0)
9646a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return -1;
9656a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    ioctl(rtc_fd, RTC_IRQP_READ, &current_rtc_freq);
9666a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (current_rtc_freq != RTC_FREQ &&
9676a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) {
9686a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        fprintf(stderr, "Could not configure '/dev/rtc' to have a 1024 Hz timer. This is not a fatal\n"
9696a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner                "error, but for better emulation accuracy either use a 2.6 host Linux kernel or\n"
9706a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner                "type 'echo 1024 > /proc/sys/dev/rtc/max-user-freq' as root.\n");
9716a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        goto fail;
9726a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
9736a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (ioctl(rtc_fd, RTC_PIE_ON, 0) < 0) {
9746a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    fail:
9756a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        close(rtc_fd);
9766a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return -1;
9776a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
9786a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
9796a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    enable_sigio_timer(rtc_fd);
9806a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
981317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    t->fd = rtc_fd;
9826a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
9836a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    return 0;
9846a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
9856a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
9866a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void rtc_stop_timer(struct qemu_alarm_timer *t)
9876a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
988317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    int rtc_fd = t->fd;
9896a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
9906a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    close(rtc_fd);
9916a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
9926a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
9936a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int dynticks_start_timer(struct qemu_alarm_timer *t)
9946a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
9956a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    struct sigevent ev;
9966a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    timer_t host_timer;
9976a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    struct sigaction act;
9986a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
9996a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    sigfillset(&act.sa_mask);
10006a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    act.sa_flags = 0;
10016a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    act.sa_handler = host_alarm_handler;
10026a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
10036a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    sigaction(SIGALRM, &act, NULL);
10046a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
10056b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner    /*
10066a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner     * Initialize ev struct to 0 to avoid valgrind complaining
10076a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner     * about uninitialized data in timer_create call
10086a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner     */
10096a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    memset(&ev, 0, sizeof(ev));
10106a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    ev.sigev_value.sival_int = 0;
10116a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    ev.sigev_notify = SIGEV_SIGNAL;
10126a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    ev.sigev_signo = SIGALRM;
10136a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
10146a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) {
10156a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        perror("timer_create");
10166a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
10176a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        /* disable dynticks */
10186a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        fprintf(stderr, "Dynamic Ticks disabled\n");
10196a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
10206a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return -1;
10216a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
10226a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
1023317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    t->timer = host_timer;
10246a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
10256a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    return 0;
10266a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
10276a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
10286a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void dynticks_stop_timer(struct qemu_alarm_timer *t)
10296a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
1030317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    timer_t host_timer = t->timer;
10316a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
10326a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    timer_delete(host_timer);
10336a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
10346a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
10356a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void dynticks_rearm_timer(struct qemu_alarm_timer *t)
10366a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
1037317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    timer_t host_timer = t->timer;
10386a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    struct itimerspec timeout;
1039317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    int64_t nearest_delta_ns = INT64_MAX;
1040317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    int64_t current_ns;
10416a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
10426a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    assert(alarm_has_dynticks(t));
10436a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (!active_timers[QEMU_CLOCK_REALTIME] &&
10446a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        !active_timers[QEMU_CLOCK_VIRTUAL] &&
10456a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        !active_timers[QEMU_CLOCK_HOST])
10466a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return;
10476a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
1048317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    nearest_delta_ns = qemu_next_alarm_deadline();
1049317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    if (nearest_delta_ns < MIN_TIMER_REARM_NS)
1050317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        nearest_delta_ns = MIN_TIMER_REARM_NS;
10516a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
10526a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    /* check whether a timer is already running */
10536a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (timer_gettime(host_timer, &timeout)) {
10546a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        perror("gettime");
10556a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        fprintf(stderr, "Internal timer error: aborting\n");
10566a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        exit(1);
10576a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
1058317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    current_ns = timeout.it_value.tv_sec * 1000000000LL + timeout.it_value.tv_nsec;
1059317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    if (current_ns && current_ns <= nearest_delta_ns)
10606a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return;
10616a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
10626a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    timeout.it_interval.tv_sec = 0;
10636a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */
1064317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    timeout.it_value.tv_sec =  nearest_delta_ns / 1000000000;
1065317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    timeout.it_value.tv_nsec = nearest_delta_ns % 1000000000;
10666a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {
10676a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        perror("settime");
10686a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        fprintf(stderr, "Internal timer error: aborting\n");
10696a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        exit(1);
10706a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
10716a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
10726a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
10736a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif /* defined(__linux__) */
10746a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
1075317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner#if !defined(_WIN32)
1076317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
10776a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int unix_start_timer(struct qemu_alarm_timer *t)
10786a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
10796a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    struct sigaction act;
10806a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    struct itimerval itv;
10816a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    int err;
10826a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
10836a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    /* timer signal */
10846a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    sigfillset(&act.sa_mask);
10856a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    act.sa_flags = 0;
10866a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    act.sa_handler = host_alarm_handler;
10876a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
10886a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    sigaction(SIGALRM, &act, NULL);
10896a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
10906a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    itv.it_interval.tv_sec = 0;
10916a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    /* for i386 kernel 2.6 to get 1 ms */
10926a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    itv.it_interval.tv_usec = 999;
10936a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    itv.it_value.tv_sec = 0;
10946a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    itv.it_value.tv_usec = 10 * 1000;
10956a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
10966a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    err = setitimer(ITIMER_REAL, &itv, NULL);
10976a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (err)
10986a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return -1;
10996a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
11006a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    return 0;
11016a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
11026a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
11036a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void unix_stop_timer(struct qemu_alarm_timer *t)
11046a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
11056a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    struct itimerval itv;
11066a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
11076a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    memset(&itv, 0, sizeof(itv));
11086a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    setitimer(ITIMER_REAL, &itv, NULL);
11096a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
11106a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
11116a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif /* !defined(_WIN32) */
11126a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
11136a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
11146a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#ifdef _WIN32
11156a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
1116317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turnerstatic MMRESULT mm_timer;
1117317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turnerstatic unsigned mm_period;
1118317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
1119317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turnerstatic void CALLBACK mm_alarm_handler(UINT uTimerID, UINT uMsg,
1120317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                                      DWORD_PTR dwUser, DWORD_PTR dw1,
1121317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                                      DWORD_PTR dw2)
1122317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner{
1123317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    struct qemu_alarm_timer *t = alarm_timer;
1124317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    if (!t) {
1125317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        return;
1126317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    }
1127317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    if (alarm_has_dynticks(t) || qemu_next_alarm_deadline() <= 0) {
1128317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        t->expired = alarm_has_dynticks(t);
1129317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        t->pending = 1;
1130317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        qemu_notify_event();
1131317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    }
1132317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner}
1133317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
1134317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turnerstatic int mm_start_timer(struct qemu_alarm_timer *t)
11356a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
11366a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    TIMECAPS tc;
11376a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    UINT flags;
11386a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
11396a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    memset(&tc, 0, sizeof(tc));
11406a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    timeGetDevCaps(&tc, sizeof(tc));
11416a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
1142317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    mm_period = tc.wPeriodMin;
1143317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    timeBeginPeriod(mm_period);
11446a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
11456a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    flags = TIME_CALLBACK_FUNCTION;
1146317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    if (alarm_has_dynticks(t)) {
11476a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        flags |= TIME_ONESHOT;
1148317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    } else {
11496a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        flags |= TIME_PERIODIC;
1150317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    }
11516a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
1152317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    mm_timer = timeSetEvent(1,                  /* interval (ms) */
1153317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                            mm_period,          /* resolution */
1154317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                            mm_alarm_handler,   /* function */
1155317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                            (DWORD_PTR)t,       /* parameter */
11566a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner                        flags);
11576a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
1158317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    if (!mm_timer) {
11596a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
11606a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner                GetLastError());
1161317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        timeEndPeriod(mm_period);
11626a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return -1;
11636a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
11646a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
11656a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    return 0;
11666a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
11676a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
1168317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turnerstatic void mm_stop_timer(struct qemu_alarm_timer *t)
11696a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
1170317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    timeKillEvent(mm_timer);
1171317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    timeEndPeriod(mm_period);
11726a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
11736a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
1174317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turnerstatic void mm_rearm_timer(struct qemu_alarm_timer *t)
11756a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
1176317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    int nearest_delta_ms;
11776a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
11786a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    assert(alarm_has_dynticks(t));
11796a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (!active_timers[QEMU_CLOCK_REALTIME] &&
11806a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        !active_timers[QEMU_CLOCK_VIRTUAL] &&
1181317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        !active_timers[QEMU_CLOCK_HOST]) {
11826a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        return;
1183317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    }
11846a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
1185317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    timeKillEvent(mm_timer);
11866a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
1187317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    nearest_delta_ms = (qemu_next_alarm_deadline() + 999999) / 1000000;
1188317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    if (nearest_delta_ms < 1) {
1189317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        nearest_delta_ms = 1;
1190317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    }
1191317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    mm_timer = timeSetEvent(nearest_delta_ms,
1192317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                            mm_period,
1193317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                            mm_alarm_handler,
1194317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                            (DWORD_PTR)t,
1195317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                            TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
11966a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
1197317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    if (!mm_timer) {
11986a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        fprintf(stderr, "Failed to re-arm win32 alarm timer %ld\n",
11996a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner                GetLastError());
12006a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
1201317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        timeEndPeriod(mm_period);
12026a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        exit(1);
12036a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
12046a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
12056a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
1206317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turnerstatic int win32_start_timer(struct qemu_alarm_timer *t)
1207317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner{
1208317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    HANDLE hTimer;
1209317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    BOOLEAN success;
1210317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
1211317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    /* If you call ChangeTimerQueueTimer on a one-shot timer (its period
1212317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner       is zero) that has already expired, the timer is not updated.  Since
1213317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner       creating a new timer is relatively expensive, set a bogus one-hour
1214317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner       interval in the dynticks case.  */
1215317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    success = CreateTimerQueueTimer(&hTimer,
1216317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                          NULL,
1217317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                          host_alarm_handler,
1218317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                          t,
1219317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                          1,
1220317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                          alarm_has_dynticks(t) ? 3600000 : 1,
1221317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                          WT_EXECUTEINTIMERTHREAD);
1222317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
1223317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    if (!success) {
1224317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
1225317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                GetLastError());
1226317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        return -1;
1227317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    }
1228317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
1229317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    t->timer = hTimer;
1230317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    return 0;
1231317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner}
1232317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
1233317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turnerstatic void win32_stop_timer(struct qemu_alarm_timer *t)
1234317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner{
1235317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    HANDLE hTimer = t->timer;
1236317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
1237317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    if (hTimer) {
1238317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        DeleteTimerQueueTimer(NULL, hTimer, NULL);
1239317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    }
1240317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner}
1241317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
1242317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turnerstatic void win32_rearm_timer(struct qemu_alarm_timer *t)
1243317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner{
1244317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    HANDLE hTimer = t->timer;
1245317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    int nearest_delta_ms;
1246317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    BOOLEAN success;
1247317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
1248317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    assert(alarm_has_dynticks(t));
1249317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    if (!active_timers[QEMU_CLOCK_REALTIME] &&
1250317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        !active_timers[QEMU_CLOCK_VIRTUAL] &&
1251317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        !active_timers[QEMU_CLOCK_HOST])
1252317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        return;
1253317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
1254317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    nearest_delta_ms = (qemu_next_alarm_deadline() + 999999) / 1000000;
1255317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    if (nearest_delta_ms < 1) {
1256317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        nearest_delta_ms = 1;
1257317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    }
1258317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    success = ChangeTimerQueueTimer(NULL,
1259317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                                    hTimer,
1260317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                                    nearest_delta_ms,
1261317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                                    3600000);
1262317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
1263317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    if (!success) {
1264317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        fprintf(stderr, "Failed to rearm win32 alarm timer: %ld\n",
1265317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner                GetLastError());
1266317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner        exit(-1);
1267317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner    }
1268317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
1269317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner}
1270317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner
12716a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif /* _WIN32 */
12726a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
12736a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void alarm_timer_on_change_state_rearm(void *opaque, int running, int reason)
12746a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
12756a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (running)
12766a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        qemu_rearm_alarm_timer((struct qemu_alarm_timer *) opaque);
12776a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
12786a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
12796a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerint init_timer_alarm(void)
12806a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
12816a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    struct qemu_alarm_timer *t = NULL;
12826a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    int i, err = -1;
12836a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
12846a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    for (i = 0; alarm_timers[i].name; i++) {
12856a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        t = &alarm_timers[i];
12866a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
12876a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        err = t->start(t);
12886a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        if (!err)
12896a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            break;
12906a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
12916a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
12926a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (err) {
12936a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        err = -ENOENT;
12946a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        goto fail;
12956a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
12966a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
12976a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    /* first event is at time 0 */
12986a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    t->pending = 1;
12996a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    alarm_timer = t;
13006a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    qemu_add_vm_change_state_handler(alarm_timer_on_change_state_rearm, t);
13016a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
13026a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    return 0;
13036a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
13046a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerfail:
13056a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    return err;
13066a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
13076a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
13086a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnervoid quit_timers(void)
13096a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
13106a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    struct qemu_alarm_timer *t = alarm_timer;
13116a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    alarm_timer = NULL;
13126a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    t->stop(t);
13136a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
13146a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
13156b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turnerextern int tcg_has_work(void);
13166b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner
13176a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerint qemu_calculate_timeout(void)
13186a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
13196a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#ifndef CONFIG_IOTHREAD
13206a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    int timeout;
13216a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
13226a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (!vm_running)
13236a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        timeout = 5000;
13246b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner    else if (tcg_has_work())
13256b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner        timeout = 0;
13266b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner    else if (!use_icount) {
13276b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner#ifdef WIN32
13286b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner        /* This corresponds to the case where the emulated system is
13296b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner         * totally idle and waiting for i/o. The problem is that on
13306b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner         * Windows, the default value will prevent Windows user events
13316b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner         * to be delivered in less than 5 seconds.
13326b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner         *
13336b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner         * Upstream contains a different way to handle this, for now
13346b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner         * this hack should be sufficient until we integrate it into
13356b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner         * our tree.
13366b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner         */
13376b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner        timeout = 1000/15;  /* deliver user events every 15/th of second */
13386b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner#else
13396b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner        timeout = 5000;
13406b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner#endif
13416b512811e01d7c81348bfa9c29c21f788ccc0a8eDavid 'Digit' Turner    } else {
13426a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner     /* XXX: use timeout computed from timers */
13436a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        int64_t add;
13446a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        int64_t delta;
13456a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        /* Advance virtual time to the next event.  */
13466a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner	delta = qemu_icount_delta();
13476a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        if (delta > 0) {
13486a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            /* If virtual time is ahead of real time then just
13496a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner               wait for IO.  */
13506a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            timeout = (delta + 999999) / 1000000;
13516a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        } else {
13526a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            /* Wait for either IO to occur or the next
13536a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner               timer event.  */
1354317c9d54284844615b33a25834a63248bf1bfa73David 'Digit' Turner            add = qemu_next_icount_deadline();
13556a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            /* We advance the timer before checking for IO.
13566a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner               Limit the amount we advance so that early IO
13576a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner               activity won't get the guest too far ahead.  */
13586a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            if (add > 10000000)
13596a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner                add = 10000000;
13606a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            delta += add;
13616a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            qemu_icount += qemu_icount_round (add);
13626a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            timeout = delta / 1000000;
13636a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            if (timeout < 0)
13646a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner                timeout = 0;
13656a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        }
13666a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
13676a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
13686a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    return timeout;
13696a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#else /* CONFIG_IOTHREAD */
13706a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    return 1000;
13716a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif
13726a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
13736a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
13746a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* Return the virtual CPU time, based on the instruction counter.  */
13756a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerint64_t cpu_get_icount(void)
13766a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{
13776a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    int64_t icount;
13786a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    CPUState *env = cpu_single_env;;
13796a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner
13806a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    icount = qemu_icount;
13816a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    if (env) {
13826a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        if (!can_do_io(env)) {
13836a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner            fprintf(stderr, "Bad clock read\n");
13846a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        }
13856a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        icount -= (env->icount_decr.u16.low + env->icount_extra);
13866a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    }
13876a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    return qemu_icount_bias + (icount << icount_time_shift);
13886a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}
1389