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, ¤t_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