1db1a4972SPaolo Bonzini /* 2db1a4972SPaolo Bonzini * QEMU System Emulator 3db1a4972SPaolo Bonzini * 4db1a4972SPaolo Bonzini * Copyright (c) 2003-2008 Fabrice Bellard 5db1a4972SPaolo Bonzini * 6db1a4972SPaolo Bonzini * Permission is hereby granted, free of charge, to any person obtaining a copy 7db1a4972SPaolo Bonzini * of this software and associated documentation files (the "Software"), to deal 8db1a4972SPaolo Bonzini * in the Software without restriction, including without limitation the rights 9db1a4972SPaolo Bonzini * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10db1a4972SPaolo Bonzini * copies of the Software, and to permit persons to whom the Software is 11db1a4972SPaolo Bonzini * furnished to do so, subject to the following conditions: 12db1a4972SPaolo Bonzini * 13db1a4972SPaolo Bonzini * The above copyright notice and this permission notice shall be included in 14db1a4972SPaolo Bonzini * all copies or substantial portions of the Software. 15db1a4972SPaolo Bonzini * 16db1a4972SPaolo Bonzini * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17db1a4972SPaolo Bonzini * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18db1a4972SPaolo Bonzini * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19db1a4972SPaolo Bonzini * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20db1a4972SPaolo Bonzini * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21db1a4972SPaolo Bonzini * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22db1a4972SPaolo Bonzini * THE SOFTWARE. 23db1a4972SPaolo Bonzini */ 24db1a4972SPaolo Bonzini 259c17d615SPaolo Bonzini #include "sysemu/sysemu.h" 2683c9089eSPaolo Bonzini #include "monitor/monitor.h" 2728ecbaeeSPaolo Bonzini #include "ui/console.h" 28db1a4972SPaolo Bonzini 29db1a4972SPaolo Bonzini #include "hw/hw.h" 30db1a4972SPaolo Bonzini 311de7afc9SPaolo Bonzini #include "qemu/timer.h" 3230ea8339SAnthony Liguori #ifdef CONFIG_POSIX 3330ea8339SAnthony Liguori #include <pthread.h> 3430ea8339SAnthony Liguori #endif 35bff9f8bfSStefan Weil 36db1a4972SPaolo Bonzini #ifdef _WIN32 37db1a4972SPaolo Bonzini #include <mmsystem.h> 38db1a4972SPaolo Bonzini #endif 39db1a4972SPaolo Bonzini 404e0c6529SAlex Bligh #ifdef CONFIG_PPOLL 414e0c6529SAlex Bligh #include <poll.h> 424e0c6529SAlex Bligh #endif 434e0c6529SAlex Bligh 44cd758dd0SAlex Bligh #ifdef CONFIG_PRCTL_PR_SET_TIMERSLACK 45cd758dd0SAlex Bligh #include <sys/prctl.h> 46cd758dd0SAlex Bligh #endif 47cd758dd0SAlex Bligh 48db1a4972SPaolo Bonzini /***********************************************************/ 49db1a4972SPaolo Bonzini /* timers */ 50db1a4972SPaolo Bonzini 51db1a4972SPaolo Bonzini struct QEMUClock { 52ff83c66eSAlex Bligh QEMUTimerList *main_loop_timerlist; 53ff83c66eSAlex Bligh QLIST_HEAD(, QEMUTimerList) timerlists; 54691a0c9cSJan Kiszka 55691a0c9cSJan Kiszka NotifierList reset_notifiers; 56691a0c9cSJan Kiszka int64_t last; 579a14b298SStefan Weil 58ff83c66eSAlex Bligh QEMUClockType type; 599a14b298SStefan Weil bool enabled; 60db1a4972SPaolo Bonzini }; 61db1a4972SPaolo Bonzini 62754d6a54SAlex Bligh QEMUTimerListGroup main_loop_tlg; 63ff83c66eSAlex Bligh QEMUClock *qemu_clocks[QEMU_CLOCK_MAX]; 64ff83c66eSAlex Bligh 65ff83c66eSAlex Bligh /* A QEMUTimerList is a list of timers attached to a clock. More 66ff83c66eSAlex Bligh * than one QEMUTimerList can be attached to each clock, for instance 67ff83c66eSAlex Bligh * used by different AioContexts / threads. Each clock also has 68ff83c66eSAlex Bligh * a list of the QEMUTimerLists associated with it, in order that 69ff83c66eSAlex Bligh * reenabling the clock can call all the notifiers. 70ff83c66eSAlex Bligh */ 71ff83c66eSAlex Bligh 72ff83c66eSAlex Bligh struct QEMUTimerList { 739a14b298SStefan Weil QEMUClock *clock; 74ff83c66eSAlex Bligh QEMUTimer *active_timers; 75ff83c66eSAlex Bligh QLIST_ENTRY(QEMUTimerList) list; 76d5541d86SAlex Bligh QEMUTimerListNotifyCB *notify_cb; 77d5541d86SAlex Bligh void *notify_opaque; 78db1a4972SPaolo Bonzini }; 79db1a4972SPaolo Bonzini 80db1a4972SPaolo Bonzini struct qemu_alarm_timer { 81db1a4972SPaolo Bonzini char const *name; 82db1a4972SPaolo Bonzini int (*start)(struct qemu_alarm_timer *t); 83db1a4972SPaolo Bonzini void (*stop)(struct qemu_alarm_timer *t); 84f3fc6e2eSPaolo Bonzini void (*rearm)(struct qemu_alarm_timer *t, int64_t nearest_delta_ns); 85cd0544eeSStefan Weil #if defined(__linux__) 86cd0544eeSStefan Weil timer_t timer; 879a14b298SStefan Weil int fd; 88cd0544eeSStefan Weil #elif defined(_WIN32) 89cd0544eeSStefan Weil HANDLE timer; 90cd0544eeSStefan Weil #endif 915e1ec7b2SStefan Weil bool expired; 925e1ec7b2SStefan Weil bool pending; 93db1a4972SPaolo Bonzini }; 94db1a4972SPaolo Bonzini 95db1a4972SPaolo Bonzini static struct qemu_alarm_timer *alarm_timer; 96db1a4972SPaolo Bonzini 97e93379b0SAlex Bligh static bool timer_expired_ns(QEMUTimer *timer_head, int64_t current_time) 9845c7b37fSStefan Weil { 9945c7b37fSStefan Weil return timer_head && (timer_head->expire_time <= current_time); 10045c7b37fSStefan Weil } 10145c7b37fSStefan Weil 102f3fc6e2eSPaolo Bonzini static int64_t qemu_next_alarm_deadline(void) 103f3fc6e2eSPaolo Bonzini { 1044ffd16fcSStefano Stabellini int64_t delta = INT64_MAX; 105f3fc6e2eSPaolo Bonzini int64_t rtdelta; 106ff83c66eSAlex Bligh int64_t hdelta; 107f3fc6e2eSPaolo Bonzini 108ff83c66eSAlex Bligh if (!use_icount && vm_clock->enabled && 109ff83c66eSAlex Bligh vm_clock->main_loop_timerlist->active_timers) { 110ff83c66eSAlex Bligh delta = vm_clock->main_loop_timerlist->active_timers->expire_time - 111f3fc6e2eSPaolo Bonzini qemu_get_clock_ns(vm_clock); 112f3fc6e2eSPaolo Bonzini } 113ff83c66eSAlex Bligh if (host_clock->enabled && 114ff83c66eSAlex Bligh host_clock->main_loop_timerlist->active_timers) { 115ff83c66eSAlex Bligh hdelta = host_clock->main_loop_timerlist->active_timers->expire_time - 116f3fc6e2eSPaolo Bonzini qemu_get_clock_ns(host_clock); 117f3fc6e2eSPaolo Bonzini if (hdelta < delta) { 118f3fc6e2eSPaolo Bonzini delta = hdelta; 119f3fc6e2eSPaolo Bonzini } 120f3fc6e2eSPaolo Bonzini } 121ff83c66eSAlex Bligh if (rt_clock->enabled && 122ff83c66eSAlex Bligh rt_clock->main_loop_timerlist->active_timers) { 123ff83c66eSAlex Bligh rtdelta = (rt_clock->main_loop_timerlist->active_timers->expire_time - 124f3fc6e2eSPaolo Bonzini qemu_get_clock_ns(rt_clock)); 125f3fc6e2eSPaolo Bonzini if (rtdelta < delta) { 126f3fc6e2eSPaolo Bonzini delta = rtdelta; 127f3fc6e2eSPaolo Bonzini } 128f3fc6e2eSPaolo Bonzini } 129f3fc6e2eSPaolo Bonzini 130f3fc6e2eSPaolo Bonzini return delta; 131f3fc6e2eSPaolo Bonzini } 132f3fc6e2eSPaolo Bonzini 133db1a4972SPaolo Bonzini static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t) 134db1a4972SPaolo Bonzini { 1358227421eSStefano Stabellini int64_t nearest_delta_ns = qemu_next_alarm_deadline(); 1368227421eSStefano Stabellini if (nearest_delta_ns < INT64_MAX) { 137f3fc6e2eSPaolo Bonzini t->rearm(t, nearest_delta_ns); 138db1a4972SPaolo Bonzini } 1398227421eSStefano Stabellini } 140db1a4972SPaolo Bonzini 1419c13246aSPaolo Bonzini /* TODO: MIN_TIMER_REARM_NS should be optimized */ 1429c13246aSPaolo Bonzini #define MIN_TIMER_REARM_NS 250000 143db1a4972SPaolo Bonzini 144db1a4972SPaolo Bonzini #ifdef _WIN32 145db1a4972SPaolo Bonzini 1462f9cba0cSStefan Weil static int mm_start_timer(struct qemu_alarm_timer *t); 1472f9cba0cSStefan Weil static void mm_stop_timer(struct qemu_alarm_timer *t); 148f3fc6e2eSPaolo Bonzini static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta); 1492f9cba0cSStefan Weil 150db1a4972SPaolo Bonzini static int win32_start_timer(struct qemu_alarm_timer *t); 151db1a4972SPaolo Bonzini static void win32_stop_timer(struct qemu_alarm_timer *t); 152f3fc6e2eSPaolo Bonzini static void win32_rearm_timer(struct qemu_alarm_timer *t, int64_t delta); 153db1a4972SPaolo Bonzini 154db1a4972SPaolo Bonzini #else 155db1a4972SPaolo Bonzini 156db1a4972SPaolo Bonzini static int unix_start_timer(struct qemu_alarm_timer *t); 157db1a4972SPaolo Bonzini static void unix_stop_timer(struct qemu_alarm_timer *t); 158f3fc6e2eSPaolo Bonzini static void unix_rearm_timer(struct qemu_alarm_timer *t, int64_t delta); 159db1a4972SPaolo Bonzini 160db1a4972SPaolo Bonzini #ifdef __linux__ 161db1a4972SPaolo Bonzini 162db1a4972SPaolo Bonzini static int dynticks_start_timer(struct qemu_alarm_timer *t); 163db1a4972SPaolo Bonzini static void dynticks_stop_timer(struct qemu_alarm_timer *t); 164f3fc6e2eSPaolo Bonzini static void dynticks_rearm_timer(struct qemu_alarm_timer *t, int64_t delta); 165db1a4972SPaolo Bonzini 166db1a4972SPaolo Bonzini #endif /* __linux__ */ 167db1a4972SPaolo Bonzini 168db1a4972SPaolo Bonzini #endif /* _WIN32 */ 169db1a4972SPaolo Bonzini 170db1a4972SPaolo Bonzini static struct qemu_alarm_timer alarm_timers[] = { 171db1a4972SPaolo Bonzini #ifndef _WIN32 172db1a4972SPaolo Bonzini #ifdef __linux__ 173db1a4972SPaolo Bonzini {"dynticks", dynticks_start_timer, 174cd0544eeSStefan Weil dynticks_stop_timer, dynticks_rearm_timer}, 175db1a4972SPaolo Bonzini #endif 17684682834SPaolo Bonzini {"unix", unix_start_timer, unix_stop_timer, unix_rearm_timer}, 177db1a4972SPaolo Bonzini #else 178cca5de73SPaolo Bonzini {"mmtimer", mm_start_timer, mm_stop_timer, mm_rearm_timer}, 179cd0544eeSStefan Weil {"dynticks", win32_start_timer, win32_stop_timer, win32_rearm_timer}, 180db1a4972SPaolo Bonzini #endif 181db1a4972SPaolo Bonzini {NULL, } 182db1a4972SPaolo Bonzini }; 183db1a4972SPaolo Bonzini 184db1a4972SPaolo Bonzini static void show_available_alarms(void) 185db1a4972SPaolo Bonzini { 186db1a4972SPaolo Bonzini int i; 187db1a4972SPaolo Bonzini 188db1a4972SPaolo Bonzini printf("Available alarm timers, in order of precedence:\n"); 189db1a4972SPaolo Bonzini for (i = 0; alarm_timers[i].name; i++) 190db1a4972SPaolo Bonzini printf("%s\n", alarm_timers[i].name); 191db1a4972SPaolo Bonzini } 192db1a4972SPaolo Bonzini 193db1a4972SPaolo Bonzini void configure_alarms(char const *opt) 194db1a4972SPaolo Bonzini { 195db1a4972SPaolo Bonzini int i; 196db1a4972SPaolo Bonzini int cur = 0; 197db1a4972SPaolo Bonzini int count = ARRAY_SIZE(alarm_timers) - 1; 198db1a4972SPaolo Bonzini char *arg; 199db1a4972SPaolo Bonzini char *name; 200db1a4972SPaolo Bonzini struct qemu_alarm_timer tmp; 201db1a4972SPaolo Bonzini 202c8057f95SPeter Maydell if (is_help_option(opt)) { 203db1a4972SPaolo Bonzini show_available_alarms(); 204db1a4972SPaolo Bonzini exit(0); 205db1a4972SPaolo Bonzini } 206db1a4972SPaolo Bonzini 2077267c094SAnthony Liguori arg = g_strdup(opt); 208db1a4972SPaolo Bonzini 209db1a4972SPaolo Bonzini /* Reorder the array */ 210db1a4972SPaolo Bonzini name = strtok(arg, ","); 211db1a4972SPaolo Bonzini while (name) { 212db1a4972SPaolo Bonzini for (i = 0; i < count && alarm_timers[i].name; i++) { 213db1a4972SPaolo Bonzini if (!strcmp(alarm_timers[i].name, name)) 214db1a4972SPaolo Bonzini break; 215db1a4972SPaolo Bonzini } 216db1a4972SPaolo Bonzini 217db1a4972SPaolo Bonzini if (i == count) { 218db1a4972SPaolo Bonzini fprintf(stderr, "Unknown clock %s\n", name); 219db1a4972SPaolo Bonzini goto next; 220db1a4972SPaolo Bonzini } 221db1a4972SPaolo Bonzini 222db1a4972SPaolo Bonzini if (i < cur) 223db1a4972SPaolo Bonzini /* Ignore */ 224db1a4972SPaolo Bonzini goto next; 225db1a4972SPaolo Bonzini 226db1a4972SPaolo Bonzini /* Swap */ 227db1a4972SPaolo Bonzini tmp = alarm_timers[i]; 228db1a4972SPaolo Bonzini alarm_timers[i] = alarm_timers[cur]; 229db1a4972SPaolo Bonzini alarm_timers[cur] = tmp; 230db1a4972SPaolo Bonzini 231db1a4972SPaolo Bonzini cur++; 232db1a4972SPaolo Bonzini next: 233db1a4972SPaolo Bonzini name = strtok(NULL, ","); 234db1a4972SPaolo Bonzini } 235db1a4972SPaolo Bonzini 2367267c094SAnthony Liguori g_free(arg); 237db1a4972SPaolo Bonzini 238db1a4972SPaolo Bonzini if (cur) { 239db1a4972SPaolo Bonzini /* Disable remaining timers */ 240db1a4972SPaolo Bonzini for (i = cur; i < count; i++) 241db1a4972SPaolo Bonzini alarm_timers[i].name = NULL; 242db1a4972SPaolo Bonzini } else { 243db1a4972SPaolo Bonzini show_available_alarms(); 244db1a4972SPaolo Bonzini exit(1); 245db1a4972SPaolo Bonzini } 246db1a4972SPaolo Bonzini } 247db1a4972SPaolo Bonzini 248d5541d86SAlex Bligh static QEMUTimerList *timerlist_new_from_clock(QEMUClock *clock, 249d5541d86SAlex Bligh QEMUTimerListNotifyCB *cb, 250d5541d86SAlex Bligh void *opaque) 251ff83c66eSAlex Bligh { 252ff83c66eSAlex Bligh QEMUTimerList *timer_list; 253db1a4972SPaolo Bonzini 254ff83c66eSAlex Bligh /* Assert if we do not have a clock. If you see this 255ff83c66eSAlex Bligh * assertion in means that the clocks have not been 256ff83c66eSAlex Bligh * initialised before a timerlist is needed. This 257ff83c66eSAlex Bligh * normally happens if an AioContext is used before 258ff83c66eSAlex Bligh * init_clocks() is called within main(). 259ff83c66eSAlex Bligh */ 260ff83c66eSAlex Bligh assert(clock); 261ff83c66eSAlex Bligh 262ff83c66eSAlex Bligh timer_list = g_malloc0(sizeof(QEMUTimerList)); 263ff83c66eSAlex Bligh timer_list->clock = clock; 264d5541d86SAlex Bligh timer_list->notify_cb = cb; 265d5541d86SAlex Bligh timer_list->notify_opaque = opaque; 266ff83c66eSAlex Bligh QLIST_INSERT_HEAD(&clock->timerlists, timer_list, list); 267ff83c66eSAlex Bligh return timer_list; 268ff83c66eSAlex Bligh } 269ff83c66eSAlex Bligh 270d5541d86SAlex Bligh QEMUTimerList *timerlist_new(QEMUClockType type, 271d5541d86SAlex Bligh QEMUTimerListNotifyCB *cb, void *opaque) 272ff83c66eSAlex Bligh { 273d5541d86SAlex Bligh return timerlist_new_from_clock(qemu_clock_ptr(type), cb, opaque); 274ff83c66eSAlex Bligh } 275ff83c66eSAlex Bligh 276ff83c66eSAlex Bligh void timerlist_free(QEMUTimerList *timer_list) 277ff83c66eSAlex Bligh { 278ff83c66eSAlex Bligh assert(!timerlist_has_timers(timer_list)); 279ff83c66eSAlex Bligh if (timer_list->clock) { 280ff83c66eSAlex Bligh QLIST_REMOVE(timer_list, list); 281ff83c66eSAlex Bligh if (timer_list->clock->main_loop_timerlist == timer_list) { 282ff83c66eSAlex Bligh timer_list->clock->main_loop_timerlist = NULL; 283ff83c66eSAlex Bligh } 284ff83c66eSAlex Bligh } 285ff83c66eSAlex Bligh g_free(timer_list); 286ff83c66eSAlex Bligh } 287ff83c66eSAlex Bligh 288ff83c66eSAlex Bligh static QEMUClock *qemu_clock_new(QEMUClockType type) 289db1a4972SPaolo Bonzini { 290db1a4972SPaolo Bonzini QEMUClock *clock; 291691a0c9cSJan Kiszka 2927267c094SAnthony Liguori clock = g_malloc0(sizeof(QEMUClock)); 293db1a4972SPaolo Bonzini clock->type = type; 2945e1ec7b2SStefan Weil clock->enabled = true; 2952ff68d07SPaolo Bonzini clock->last = INT64_MIN; 296ff83c66eSAlex Bligh QLIST_INIT(&clock->timerlists); 297691a0c9cSJan Kiszka notifier_list_init(&clock->reset_notifiers); 298d5541d86SAlex Bligh clock->main_loop_timerlist = timerlist_new_from_clock(clock, NULL, NULL); 299db1a4972SPaolo Bonzini return clock; 300db1a4972SPaolo Bonzini } 301db1a4972SPaolo Bonzini 302ff83c66eSAlex Bligh bool qemu_clock_use_for_deadline(QEMUClock *clock) 303ff83c66eSAlex Bligh { 304ff83c66eSAlex Bligh return !(use_icount && (clock->type == QEMU_CLOCK_VIRTUAL)); 305ff83c66eSAlex Bligh } 306ff83c66eSAlex Bligh 307b1bbfe72SAlex Bligh void qemu_clock_notify(QEMUClock *clock) 308b1bbfe72SAlex Bligh { 309b1bbfe72SAlex Bligh QEMUTimerList *timer_list; 310b1bbfe72SAlex Bligh QLIST_FOREACH(timer_list, &clock->timerlists, list) { 311b1bbfe72SAlex Bligh timerlist_notify(timer_list); 312b1bbfe72SAlex Bligh } 313b1bbfe72SAlex Bligh } 314b1bbfe72SAlex Bligh 3155e1ec7b2SStefan Weil void qemu_clock_enable(QEMUClock *clock, bool enabled) 316db1a4972SPaolo Bonzini { 317fbdc14ebSPaolo Bonzini bool old = clock->enabled; 318db1a4972SPaolo Bonzini clock->enabled = enabled; 319fbdc14ebSPaolo Bonzini if (enabled && !old) { 320b1bbfe72SAlex Bligh qemu_clock_notify(clock); 321fbdc14ebSPaolo Bonzini qemu_rearm_alarm_timer(alarm_timer); 322fbdc14ebSPaolo Bonzini } 323db1a4972SPaolo Bonzini } 324db1a4972SPaolo Bonzini 325ff83c66eSAlex Bligh bool timerlist_has_timers(QEMUTimerList *timer_list) 326dc2dfcf0SPaolo Bonzini { 327ff83c66eSAlex Bligh return !!timer_list->active_timers; 328dc2dfcf0SPaolo Bonzini } 329dc2dfcf0SPaolo Bonzini 330ff83c66eSAlex Bligh bool qemu_clock_has_timers(QEMUClock *clock) 331dc2dfcf0SPaolo Bonzini { 332ff83c66eSAlex Bligh return timerlist_has_timers(clock->main_loop_timerlist); 333dc2dfcf0SPaolo Bonzini } 334dc2dfcf0SPaolo Bonzini 335ff83c66eSAlex Bligh bool timerlist_expired(QEMUTimerList *timer_list) 336ff83c66eSAlex Bligh { 337ff83c66eSAlex Bligh return (timer_list->active_timers && 338ff83c66eSAlex Bligh timer_list->active_timers->expire_time < 339ff83c66eSAlex Bligh qemu_get_clock_ns(timer_list->clock)); 340ff83c66eSAlex Bligh } 341ff83c66eSAlex Bligh 342ff83c66eSAlex Bligh bool qemu_clock_expired(QEMUClock *clock) 343ff83c66eSAlex Bligh { 344ff83c66eSAlex Bligh return timerlist_expired(clock->main_loop_timerlist); 345ff83c66eSAlex Bligh } 346ff83c66eSAlex Bligh 347ff83c66eSAlex Bligh int64_t timerlist_deadline(QEMUTimerList *timer_list) 348dc2dfcf0SPaolo Bonzini { 349dc2dfcf0SPaolo Bonzini /* To avoid problems with overflow limit this to 2^32. */ 350dc2dfcf0SPaolo Bonzini int64_t delta = INT32_MAX; 351dc2dfcf0SPaolo Bonzini 352ff83c66eSAlex Bligh if (timer_list->clock->enabled && timer_list->active_timers) { 353ff83c66eSAlex Bligh delta = timer_list->active_timers->expire_time - 354ff83c66eSAlex Bligh qemu_get_clock_ns(timer_list->clock); 355dc2dfcf0SPaolo Bonzini } 356dc2dfcf0SPaolo Bonzini if (delta < 0) { 357dc2dfcf0SPaolo Bonzini delta = 0; 358dc2dfcf0SPaolo Bonzini } 359dc2dfcf0SPaolo Bonzini return delta; 360dc2dfcf0SPaolo Bonzini } 361dc2dfcf0SPaolo Bonzini 362ff83c66eSAlex Bligh int64_t qemu_clock_deadline(QEMUClock *clock) 363ff83c66eSAlex Bligh { 364ff83c66eSAlex Bligh return timerlist_deadline(clock->main_loop_timerlist); 365ff83c66eSAlex Bligh } 366ff83c66eSAlex Bligh 36702a03a9fSAlex Bligh /* 36802a03a9fSAlex Bligh * As above, but return -1 for no deadline, and do not cap to 2^32 36902a03a9fSAlex Bligh * as we know the result is always positive. 37002a03a9fSAlex Bligh */ 37102a03a9fSAlex Bligh 372ff83c66eSAlex Bligh int64_t timerlist_deadline_ns(QEMUTimerList *timer_list) 37302a03a9fSAlex Bligh { 37402a03a9fSAlex Bligh int64_t delta; 37502a03a9fSAlex Bligh 376ff83c66eSAlex Bligh if (!timer_list->clock->enabled || !timer_list->active_timers) { 37702a03a9fSAlex Bligh return -1; 37802a03a9fSAlex Bligh } 37902a03a9fSAlex Bligh 380ff83c66eSAlex Bligh delta = timer_list->active_timers->expire_time - 381ff83c66eSAlex Bligh qemu_get_clock_ns(timer_list->clock); 38202a03a9fSAlex Bligh 38302a03a9fSAlex Bligh if (delta <= 0) { 38402a03a9fSAlex Bligh return 0; 38502a03a9fSAlex Bligh } 38602a03a9fSAlex Bligh 38702a03a9fSAlex Bligh return delta; 38802a03a9fSAlex Bligh } 38902a03a9fSAlex Bligh 390ff83c66eSAlex Bligh int64_t qemu_clock_deadline_ns(QEMUClock *clock) 391ff83c66eSAlex Bligh { 392ff83c66eSAlex Bligh return timerlist_deadline_ns(clock->main_loop_timerlist); 393ff83c66eSAlex Bligh } 394ff83c66eSAlex Bligh 395*ac70aafcSAlex Bligh /* Calculate the soonest deadline across all timerlists attached 396*ac70aafcSAlex Bligh * to the clock. This is used for the icount timeout so we 397*ac70aafcSAlex Bligh * ignore whether or not the clock should be used in deadline 398*ac70aafcSAlex Bligh * calculations. 399*ac70aafcSAlex Bligh */ 400*ac70aafcSAlex Bligh int64_t qemu_clock_deadline_ns_all(QEMUClock *clock) 401*ac70aafcSAlex Bligh { 402*ac70aafcSAlex Bligh int64_t deadline = -1; 403*ac70aafcSAlex Bligh QEMUTimerList *timer_list; 404*ac70aafcSAlex Bligh QLIST_FOREACH(timer_list, &clock->timerlists, list) { 405*ac70aafcSAlex Bligh deadline = qemu_soonest_timeout(deadline, 406*ac70aafcSAlex Bligh timerlist_deadline_ns(timer_list)); 407*ac70aafcSAlex Bligh } 408*ac70aafcSAlex Bligh return deadline; 409*ac70aafcSAlex Bligh } 410*ac70aafcSAlex Bligh 411ff83c66eSAlex Bligh QEMUClock *timerlist_get_clock(QEMUTimerList *timer_list) 412ff83c66eSAlex Bligh { 413ff83c66eSAlex Bligh return timer_list->clock; 414ff83c66eSAlex Bligh } 415ff83c66eSAlex Bligh 416ff83c66eSAlex Bligh QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClock *clock) 417ff83c66eSAlex Bligh { 418ff83c66eSAlex Bligh return clock->main_loop_timerlist; 419ff83c66eSAlex Bligh } 420ff83c66eSAlex Bligh 421d5541d86SAlex Bligh void timerlist_notify(QEMUTimerList *timer_list) 422d5541d86SAlex Bligh { 423d5541d86SAlex Bligh if (timer_list->notify_cb) { 424d5541d86SAlex Bligh timer_list->notify_cb(timer_list->notify_opaque); 425d5541d86SAlex Bligh } else { 426d5541d86SAlex Bligh qemu_notify_event(); 427d5541d86SAlex Bligh } 428d5541d86SAlex Bligh } 429d5541d86SAlex Bligh 43002a03a9fSAlex Bligh /* Transition function to convert a nanosecond timeout to ms 43102a03a9fSAlex Bligh * This is used where a system does not support ppoll 43202a03a9fSAlex Bligh */ 43302a03a9fSAlex Bligh int qemu_timeout_ns_to_ms(int64_t ns) 43402a03a9fSAlex Bligh { 43502a03a9fSAlex Bligh int64_t ms; 43602a03a9fSAlex Bligh if (ns < 0) { 43702a03a9fSAlex Bligh return -1; 43802a03a9fSAlex Bligh } 43902a03a9fSAlex Bligh 44002a03a9fSAlex Bligh if (!ns) { 44102a03a9fSAlex Bligh return 0; 44202a03a9fSAlex Bligh } 44302a03a9fSAlex Bligh 44402a03a9fSAlex Bligh /* Always round up, because it's better to wait too long than to wait too 44502a03a9fSAlex Bligh * little and effectively busy-wait 44602a03a9fSAlex Bligh */ 44702a03a9fSAlex Bligh ms = (ns + SCALE_MS - 1) / SCALE_MS; 44802a03a9fSAlex Bligh 44902a03a9fSAlex Bligh /* To avoid overflow problems, limit this to 2^31, i.e. approx 25 days */ 45002a03a9fSAlex Bligh if (ms > (int64_t) INT32_MAX) { 45102a03a9fSAlex Bligh ms = INT32_MAX; 45202a03a9fSAlex Bligh } 45302a03a9fSAlex Bligh 45402a03a9fSAlex Bligh return (int) ms; 45502a03a9fSAlex Bligh } 45602a03a9fSAlex Bligh 45702a03a9fSAlex Bligh 4584e0c6529SAlex Bligh /* qemu implementation of g_poll which uses a nanosecond timeout but is 4594e0c6529SAlex Bligh * otherwise identical to g_poll 4604e0c6529SAlex Bligh */ 4614e0c6529SAlex Bligh int qemu_poll_ns(GPollFD *fds, guint nfds, int64_t timeout) 4624e0c6529SAlex Bligh { 4634e0c6529SAlex Bligh #ifdef CONFIG_PPOLL 4644e0c6529SAlex Bligh if (timeout < 0) { 4654e0c6529SAlex Bligh return ppoll((struct pollfd *)fds, nfds, NULL, NULL); 4664e0c6529SAlex Bligh } else { 4674e0c6529SAlex Bligh struct timespec ts; 4684e0c6529SAlex Bligh ts.tv_sec = timeout / 1000000000LL; 4694e0c6529SAlex Bligh ts.tv_nsec = timeout % 1000000000LL; 4704e0c6529SAlex Bligh return ppoll((struct pollfd *)fds, nfds, &ts, NULL); 4714e0c6529SAlex Bligh } 4724e0c6529SAlex Bligh #else 4734e0c6529SAlex Bligh return g_poll(fds, nfds, qemu_timeout_ns_to_ms(timeout)); 4744e0c6529SAlex Bligh #endif 4754e0c6529SAlex Bligh } 4764e0c6529SAlex Bligh 4774e0c6529SAlex Bligh 478ff83c66eSAlex Bligh void timer_init(QEMUTimer *ts, 479ff83c66eSAlex Bligh QEMUTimerList *timer_list, int scale, 4804a998740SPaolo Bonzini QEMUTimerCB *cb, void *opaque) 481db1a4972SPaolo Bonzini { 482ff83c66eSAlex Bligh ts->timer_list = timer_list; 483db1a4972SPaolo Bonzini ts->cb = cb; 484db1a4972SPaolo Bonzini ts->opaque = opaque; 4854a998740SPaolo Bonzini ts->scale = scale; 486ff83c66eSAlex Bligh } 487ff83c66eSAlex Bligh 488ff83c66eSAlex Bligh QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale, 489ff83c66eSAlex Bligh QEMUTimerCB *cb, void *opaque) 490ff83c66eSAlex Bligh { 491ff83c66eSAlex Bligh return timer_new_tl(clock->main_loop_timerlist, 492ff83c66eSAlex Bligh scale, cb, opaque); 493db1a4972SPaolo Bonzini } 494db1a4972SPaolo Bonzini 495db1a4972SPaolo Bonzini void qemu_free_timer(QEMUTimer *ts) 496db1a4972SPaolo Bonzini { 4977267c094SAnthony Liguori g_free(ts); 498db1a4972SPaolo Bonzini } 499db1a4972SPaolo Bonzini 500db1a4972SPaolo Bonzini /* stop a timer, but do not dealloc it */ 501db1a4972SPaolo Bonzini void qemu_del_timer(QEMUTimer *ts) 502db1a4972SPaolo Bonzini { 503db1a4972SPaolo Bonzini QEMUTimer **pt, *t; 504db1a4972SPaolo Bonzini 505db1a4972SPaolo Bonzini /* NOTE: this code must be signal safe because 506e93379b0SAlex Bligh timer_expired() can be called from a signal. */ 507ff83c66eSAlex Bligh pt = &ts->timer_list->active_timers; 508db1a4972SPaolo Bonzini for(;;) { 509db1a4972SPaolo Bonzini t = *pt; 510db1a4972SPaolo Bonzini if (!t) 511db1a4972SPaolo Bonzini break; 512db1a4972SPaolo Bonzini if (t == ts) { 513db1a4972SPaolo Bonzini *pt = t->next; 514db1a4972SPaolo Bonzini break; 515db1a4972SPaolo Bonzini } 516db1a4972SPaolo Bonzini pt = &t->next; 517db1a4972SPaolo Bonzini } 518db1a4972SPaolo Bonzini } 519db1a4972SPaolo Bonzini 520db1a4972SPaolo Bonzini /* modify the current timer so that it will be fired when current_time 521db1a4972SPaolo Bonzini >= expire_time. The corresponding callback will be called. */ 5222ff68d07SPaolo Bonzini void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time) 523db1a4972SPaolo Bonzini { 524db1a4972SPaolo Bonzini QEMUTimer **pt, *t; 525db1a4972SPaolo Bonzini 526db1a4972SPaolo Bonzini qemu_del_timer(ts); 527db1a4972SPaolo Bonzini 528db1a4972SPaolo Bonzini /* add the timer in the sorted list */ 529db1a4972SPaolo Bonzini /* NOTE: this code must be signal safe because 530e93379b0SAlex Bligh timer_expired() can be called from a signal. */ 531ff83c66eSAlex Bligh pt = &ts->timer_list->active_timers; 532db1a4972SPaolo Bonzini for(;;) { 533db1a4972SPaolo Bonzini t = *pt; 534e93379b0SAlex Bligh if (!timer_expired_ns(t, expire_time)) { 535db1a4972SPaolo Bonzini break; 53645c7b37fSStefan Weil } 537db1a4972SPaolo Bonzini pt = &t->next; 538db1a4972SPaolo Bonzini } 539db1a4972SPaolo Bonzini ts->expire_time = expire_time; 540db1a4972SPaolo Bonzini ts->next = *pt; 541db1a4972SPaolo Bonzini *pt = ts; 542db1a4972SPaolo Bonzini 543db1a4972SPaolo Bonzini /* Rearm if necessary */ 544ff83c66eSAlex Bligh if (pt == &ts->timer_list->active_timers) { 545db1a4972SPaolo Bonzini if (!alarm_timer->pending) { 546db1a4972SPaolo Bonzini qemu_rearm_alarm_timer(alarm_timer); 547db1a4972SPaolo Bonzini } 548db1a4972SPaolo Bonzini /* Interrupt execution to force deadline recalculation. */ 549ff83c66eSAlex Bligh qemu_clock_warp(ts->timer_list->clock); 550d5541d86SAlex Bligh timerlist_notify(ts->timer_list); 551db1a4972SPaolo Bonzini } 552db1a4972SPaolo Bonzini } 553db1a4972SPaolo Bonzini 5544a998740SPaolo Bonzini void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time) 5554a998740SPaolo Bonzini { 5564a998740SPaolo Bonzini qemu_mod_timer_ns(ts, expire_time * ts->scale); 5574a998740SPaolo Bonzini } 5584a998740SPaolo Bonzini 559e93379b0SAlex Bligh bool timer_pending(QEMUTimer *ts) 560db1a4972SPaolo Bonzini { 561db1a4972SPaolo Bonzini QEMUTimer *t; 562ff83c66eSAlex Bligh for (t = ts->timer_list->active_timers; t != NULL; t = t->next) { 5635e1ec7b2SStefan Weil if (t == ts) { 5645e1ec7b2SStefan Weil return true; 565db1a4972SPaolo Bonzini } 5665e1ec7b2SStefan Weil } 5675e1ec7b2SStefan Weil return false; 568db1a4972SPaolo Bonzini } 569db1a4972SPaolo Bonzini 570e93379b0SAlex Bligh bool timer_expired(QEMUTimer *timer_head, int64_t current_time) 571db1a4972SPaolo Bonzini { 572e93379b0SAlex Bligh return timer_expired_ns(timer_head, current_time * timer_head->scale); 573db1a4972SPaolo Bonzini } 574db1a4972SPaolo Bonzini 575ff83c66eSAlex Bligh bool timerlist_run_timers(QEMUTimerList *timer_list) 576db1a4972SPaolo Bonzini { 577144b97c2SPaolo Bonzini QEMUTimer *ts; 578db1a4972SPaolo Bonzini int64_t current_time; 579f9a976b7SAlex Bligh bool progress = false; 580db1a4972SPaolo Bonzini 581ff83c66eSAlex Bligh if (!timer_list->clock->enabled) { 582f9a976b7SAlex Bligh return progress; 583ff83c66eSAlex Bligh } 584db1a4972SPaolo Bonzini 585ff83c66eSAlex Bligh current_time = qemu_get_clock_ns(timer_list->clock); 586db1a4972SPaolo Bonzini for(;;) { 587ff83c66eSAlex Bligh ts = timer_list->active_timers; 588e93379b0SAlex Bligh if (!timer_expired_ns(ts, current_time)) { 589db1a4972SPaolo Bonzini break; 59045c7b37fSStefan Weil } 591db1a4972SPaolo Bonzini /* remove timer from the list before calling the callback */ 592ff83c66eSAlex Bligh timer_list->active_timers = ts->next; 593db1a4972SPaolo Bonzini ts->next = NULL; 594db1a4972SPaolo Bonzini 595db1a4972SPaolo Bonzini /* run the callback (the timer list can be modified) */ 596db1a4972SPaolo Bonzini ts->cb(ts->opaque); 597f9a976b7SAlex Bligh progress = true; 598db1a4972SPaolo Bonzini } 599f9a976b7SAlex Bligh return progress; 600db1a4972SPaolo Bonzini } 601db1a4972SPaolo Bonzini 602ff83c66eSAlex Bligh bool qemu_run_timers(QEMUClock *clock) 603ff83c66eSAlex Bligh { 604ff83c66eSAlex Bligh return timerlist_run_timers(clock->main_loop_timerlist); 605ff83c66eSAlex Bligh } 606ff83c66eSAlex Bligh 607d5541d86SAlex Bligh void timerlistgroup_init(QEMUTimerListGroup *tlg, 608d5541d86SAlex Bligh QEMUTimerListNotifyCB *cb, void *opaque) 609754d6a54SAlex Bligh { 610754d6a54SAlex Bligh QEMUClockType type; 611754d6a54SAlex Bligh for (type = 0; type < QEMU_CLOCK_MAX; type++) { 612d5541d86SAlex Bligh tlg->tl[type] = timerlist_new(type, cb, opaque); 613754d6a54SAlex Bligh } 614754d6a54SAlex Bligh } 615754d6a54SAlex Bligh 616754d6a54SAlex Bligh void timerlistgroup_deinit(QEMUTimerListGroup *tlg) 617754d6a54SAlex Bligh { 618754d6a54SAlex Bligh QEMUClockType type; 619754d6a54SAlex Bligh for (type = 0; type < QEMU_CLOCK_MAX; type++) { 620754d6a54SAlex Bligh timerlist_free(tlg->tl[type]); 621754d6a54SAlex Bligh } 622754d6a54SAlex Bligh } 623754d6a54SAlex Bligh 624754d6a54SAlex Bligh bool timerlistgroup_run_timers(QEMUTimerListGroup *tlg) 625754d6a54SAlex Bligh { 626754d6a54SAlex Bligh QEMUClockType type; 627754d6a54SAlex Bligh bool progress = false; 628754d6a54SAlex Bligh for (type = 0; type < QEMU_CLOCK_MAX; type++) { 629754d6a54SAlex Bligh progress |= timerlist_run_timers(tlg->tl[type]); 630754d6a54SAlex Bligh } 631754d6a54SAlex Bligh return progress; 632754d6a54SAlex Bligh } 633754d6a54SAlex Bligh 634754d6a54SAlex Bligh int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg) 635754d6a54SAlex Bligh { 636754d6a54SAlex Bligh int64_t deadline = -1; 637754d6a54SAlex Bligh QEMUClockType type; 638754d6a54SAlex Bligh for (type = 0; type < QEMU_CLOCK_MAX; type++) { 639754d6a54SAlex Bligh if (qemu_clock_use_for_deadline(tlg->tl[type]->clock)) { 640754d6a54SAlex Bligh deadline = qemu_soonest_timeout(deadline, 641754d6a54SAlex Bligh timerlist_deadline_ns( 642754d6a54SAlex Bligh tlg->tl[type])); 643754d6a54SAlex Bligh } 644754d6a54SAlex Bligh } 645754d6a54SAlex Bligh return deadline; 646754d6a54SAlex Bligh } 647754d6a54SAlex Bligh 648db1a4972SPaolo Bonzini int64_t qemu_get_clock_ns(QEMUClock *clock) 649db1a4972SPaolo Bonzini { 650691a0c9cSJan Kiszka int64_t now, last; 651691a0c9cSJan Kiszka 652db1a4972SPaolo Bonzini switch(clock->type) { 653db1a4972SPaolo Bonzini case QEMU_CLOCK_REALTIME: 654db1a4972SPaolo Bonzini return get_clock(); 655db1a4972SPaolo Bonzini default: 656db1a4972SPaolo Bonzini case QEMU_CLOCK_VIRTUAL: 657db1a4972SPaolo Bonzini if (use_icount) { 658db1a4972SPaolo Bonzini return cpu_get_icount(); 659db1a4972SPaolo Bonzini } else { 660db1a4972SPaolo Bonzini return cpu_get_clock(); 661db1a4972SPaolo Bonzini } 662db1a4972SPaolo Bonzini case QEMU_CLOCK_HOST: 663691a0c9cSJan Kiszka now = get_clock_realtime(); 664691a0c9cSJan Kiszka last = clock->last; 665691a0c9cSJan Kiszka clock->last = now; 666691a0c9cSJan Kiszka if (now < last) { 667691a0c9cSJan Kiszka notifier_list_notify(&clock->reset_notifiers, &now); 668db1a4972SPaolo Bonzini } 669691a0c9cSJan Kiszka return now; 670691a0c9cSJan Kiszka } 671691a0c9cSJan Kiszka } 672691a0c9cSJan Kiszka 673691a0c9cSJan Kiszka void qemu_register_clock_reset_notifier(QEMUClock *clock, Notifier *notifier) 674691a0c9cSJan Kiszka { 675691a0c9cSJan Kiszka notifier_list_add(&clock->reset_notifiers, notifier); 676691a0c9cSJan Kiszka } 677691a0c9cSJan Kiszka 678691a0c9cSJan Kiszka void qemu_unregister_clock_reset_notifier(QEMUClock *clock, Notifier *notifier) 679691a0c9cSJan Kiszka { 68031552529SPaolo Bonzini notifier_remove(notifier); 681db1a4972SPaolo Bonzini } 682db1a4972SPaolo Bonzini 683db1a4972SPaolo Bonzini void init_clocks(void) 684db1a4972SPaolo Bonzini { 685ff83c66eSAlex Bligh QEMUClockType type; 686ff83c66eSAlex Bligh for (type = 0; type < QEMU_CLOCK_MAX; type++) { 687ff83c66eSAlex Bligh if (!qemu_clocks[type]) { 688ff83c66eSAlex Bligh qemu_clocks[type] = qemu_clock_new(type); 689754d6a54SAlex Bligh main_loop_tlg.tl[type] = qemu_clocks[type]->main_loop_timerlist; 690db1a4972SPaolo Bonzini } 691ff83c66eSAlex Bligh } 692ff83c66eSAlex Bligh 693cd758dd0SAlex Bligh #ifdef CONFIG_PRCTL_PR_SET_TIMERSLACK 694cd758dd0SAlex Bligh prctl(PR_SET_TIMERSLACK, 1, 0, 0, 0); 695cd758dd0SAlex Bligh #endif 696744ca8e3SPaolo Bonzini } 697db1a4972SPaolo Bonzini 698e93379b0SAlex Bligh uint64_t timer_expire_time_ns(QEMUTimer *ts) 699db1a4972SPaolo Bonzini { 700e93379b0SAlex Bligh return timer_pending(ts) ? ts->expire_time : -1; 701db1a4972SPaolo Bonzini } 702db1a4972SPaolo Bonzini 703f9a976b7SAlex Bligh bool qemu_run_all_timers(void) 704db1a4972SPaolo Bonzini { 705f9a976b7SAlex Bligh bool progress = false; 7065e1ec7b2SStefan Weil alarm_timer->pending = false; 707ca5a2a4bSPaolo Bonzini 708158fd3ceSPeter Portante /* vm time timers */ 709ff83c66eSAlex Bligh QEMUClockType type; 710ff83c66eSAlex Bligh for (type = 0; type < QEMU_CLOCK_MAX; type++) { 711ff83c66eSAlex Bligh progress |= qemu_run_timers(qemu_clock_ptr(type)); 712ff83c66eSAlex Bligh } 713158fd3ceSPeter Portante 714db1a4972SPaolo Bonzini /* rearm timer, if not periodic */ 715db1a4972SPaolo Bonzini if (alarm_timer->expired) { 7165e1ec7b2SStefan Weil alarm_timer->expired = false; 717db1a4972SPaolo Bonzini qemu_rearm_alarm_timer(alarm_timer); 718db1a4972SPaolo Bonzini } 719f9a976b7SAlex Bligh 720f9a976b7SAlex Bligh return progress; 721db1a4972SPaolo Bonzini } 722db1a4972SPaolo Bonzini 723db1a4972SPaolo Bonzini #ifdef _WIN32 72468c23e55SPaolo Bonzini static void CALLBACK host_alarm_handler(PVOID lpParam, BOOLEAN unused) 725db1a4972SPaolo Bonzini #else 726db1a4972SPaolo Bonzini static void host_alarm_handler(int host_signum) 727db1a4972SPaolo Bonzini #endif 728db1a4972SPaolo Bonzini { 729db1a4972SPaolo Bonzini struct qemu_alarm_timer *t = alarm_timer; 730db1a4972SPaolo Bonzini if (!t) 731db1a4972SPaolo Bonzini return; 732db1a4972SPaolo Bonzini 7338205199dSStefan Weil t->expired = true; 7345e1ec7b2SStefan Weil t->pending = true; 735db1a4972SPaolo Bonzini qemu_notify_event(); 736db1a4972SPaolo Bonzini } 737db1a4972SPaolo Bonzini 7384c3d45ebSPaolo Bonzini #if defined(__linux__) 7394c3d45ebSPaolo Bonzini 7401de7afc9SPaolo Bonzini #include "qemu/compatfd.h" 741d25f89c9SJan Kiszka 742db1a4972SPaolo Bonzini static int dynticks_start_timer(struct qemu_alarm_timer *t) 743db1a4972SPaolo Bonzini { 744db1a4972SPaolo Bonzini struct sigevent ev; 745db1a4972SPaolo Bonzini timer_t host_timer; 746db1a4972SPaolo Bonzini struct sigaction act; 747db1a4972SPaolo Bonzini 748db1a4972SPaolo Bonzini sigfillset(&act.sa_mask); 749db1a4972SPaolo Bonzini act.sa_flags = 0; 750db1a4972SPaolo Bonzini act.sa_handler = host_alarm_handler; 751db1a4972SPaolo Bonzini 752db1a4972SPaolo Bonzini sigaction(SIGALRM, &act, NULL); 753db1a4972SPaolo Bonzini 754db1a4972SPaolo Bonzini /* 755db1a4972SPaolo Bonzini * Initialize ev struct to 0 to avoid valgrind complaining 756db1a4972SPaolo Bonzini * about uninitialized data in timer_create call 757db1a4972SPaolo Bonzini */ 758db1a4972SPaolo Bonzini memset(&ev, 0, sizeof(ev)); 759db1a4972SPaolo Bonzini ev.sigev_value.sival_int = 0; 760db1a4972SPaolo Bonzini ev.sigev_notify = SIGEV_SIGNAL; 7611e9737daSRichard Henderson #ifdef CONFIG_SIGEV_THREAD_ID 762d25f89c9SJan Kiszka if (qemu_signalfd_available()) { 763d25f89c9SJan Kiszka ev.sigev_notify = SIGEV_THREAD_ID; 764d25f89c9SJan Kiszka ev._sigev_un._tid = qemu_get_thread_id(); 765d25f89c9SJan Kiszka } 7661e9737daSRichard Henderson #endif /* CONFIG_SIGEV_THREAD_ID */ 767db1a4972SPaolo Bonzini ev.sigev_signo = SIGALRM; 768db1a4972SPaolo Bonzini 769db1a4972SPaolo Bonzini if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) { 770db1a4972SPaolo Bonzini perror("timer_create"); 771db1a4972SPaolo Bonzini return -1; 772db1a4972SPaolo Bonzini } 773db1a4972SPaolo Bonzini 774cd0544eeSStefan Weil t->timer = host_timer; 775db1a4972SPaolo Bonzini 776db1a4972SPaolo Bonzini return 0; 777db1a4972SPaolo Bonzini } 778db1a4972SPaolo Bonzini 779db1a4972SPaolo Bonzini static void dynticks_stop_timer(struct qemu_alarm_timer *t) 780db1a4972SPaolo Bonzini { 781cd0544eeSStefan Weil timer_t host_timer = t->timer; 782db1a4972SPaolo Bonzini 783db1a4972SPaolo Bonzini timer_delete(host_timer); 784db1a4972SPaolo Bonzini } 785db1a4972SPaolo Bonzini 786f3fc6e2eSPaolo Bonzini static void dynticks_rearm_timer(struct qemu_alarm_timer *t, 787f3fc6e2eSPaolo Bonzini int64_t nearest_delta_ns) 788db1a4972SPaolo Bonzini { 789cd0544eeSStefan Weil timer_t host_timer = t->timer; 790db1a4972SPaolo Bonzini struct itimerspec timeout; 7919c13246aSPaolo Bonzini int64_t current_ns; 792db1a4972SPaolo Bonzini 7934c3d45ebSPaolo Bonzini if (nearest_delta_ns < MIN_TIMER_REARM_NS) 7944c3d45ebSPaolo Bonzini nearest_delta_ns = MIN_TIMER_REARM_NS; 795db1a4972SPaolo Bonzini 796db1a4972SPaolo Bonzini /* check whether a timer is already running */ 797db1a4972SPaolo Bonzini if (timer_gettime(host_timer, &timeout)) { 798db1a4972SPaolo Bonzini perror("gettime"); 799db1a4972SPaolo Bonzini fprintf(stderr, "Internal timer error: aborting\n"); 800db1a4972SPaolo Bonzini exit(1); 801db1a4972SPaolo Bonzini } 8029c13246aSPaolo Bonzini current_ns = timeout.it_value.tv_sec * 1000000000LL + timeout.it_value.tv_nsec; 8039c13246aSPaolo Bonzini if (current_ns && current_ns <= nearest_delta_ns) 804db1a4972SPaolo Bonzini return; 805db1a4972SPaolo Bonzini 806db1a4972SPaolo Bonzini timeout.it_interval.tv_sec = 0; 807db1a4972SPaolo Bonzini timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */ 8089c13246aSPaolo Bonzini timeout.it_value.tv_sec = nearest_delta_ns / 1000000000; 8099c13246aSPaolo Bonzini timeout.it_value.tv_nsec = nearest_delta_ns % 1000000000; 810db1a4972SPaolo Bonzini if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) { 811db1a4972SPaolo Bonzini perror("settime"); 812db1a4972SPaolo Bonzini fprintf(stderr, "Internal timer error: aborting\n"); 813db1a4972SPaolo Bonzini exit(1); 814db1a4972SPaolo Bonzini } 815db1a4972SPaolo Bonzini } 816db1a4972SPaolo Bonzini 817db1a4972SPaolo Bonzini #endif /* defined(__linux__) */ 818db1a4972SPaolo Bonzini 819f26e5a54SStefan Weil #if !defined(_WIN32) 820f26e5a54SStefan Weil 821db1a4972SPaolo Bonzini static int unix_start_timer(struct qemu_alarm_timer *t) 822db1a4972SPaolo Bonzini { 823db1a4972SPaolo Bonzini struct sigaction act; 824db1a4972SPaolo Bonzini 825db1a4972SPaolo Bonzini /* timer signal */ 826db1a4972SPaolo Bonzini sigfillset(&act.sa_mask); 827db1a4972SPaolo Bonzini act.sa_flags = 0; 828db1a4972SPaolo Bonzini act.sa_handler = host_alarm_handler; 829db1a4972SPaolo Bonzini 830db1a4972SPaolo Bonzini sigaction(SIGALRM, &act, NULL); 83184682834SPaolo Bonzini return 0; 83284682834SPaolo Bonzini } 83384682834SPaolo Bonzini 834f3fc6e2eSPaolo Bonzini static void unix_rearm_timer(struct qemu_alarm_timer *t, 835f3fc6e2eSPaolo Bonzini int64_t nearest_delta_ns) 83684682834SPaolo Bonzini { 83784682834SPaolo Bonzini struct itimerval itv; 83884682834SPaolo Bonzini int err; 83984682834SPaolo Bonzini 84084682834SPaolo Bonzini if (nearest_delta_ns < MIN_TIMER_REARM_NS) 84184682834SPaolo Bonzini nearest_delta_ns = MIN_TIMER_REARM_NS; 842db1a4972SPaolo Bonzini 843db1a4972SPaolo Bonzini itv.it_interval.tv_sec = 0; 84484682834SPaolo Bonzini itv.it_interval.tv_usec = 0; /* 0 for one-shot timer */ 84584682834SPaolo Bonzini itv.it_value.tv_sec = nearest_delta_ns / 1000000000; 84684682834SPaolo Bonzini itv.it_value.tv_usec = (nearest_delta_ns % 1000000000) / 1000; 847db1a4972SPaolo Bonzini err = setitimer(ITIMER_REAL, &itv, NULL); 84884682834SPaolo Bonzini if (err) { 84984682834SPaolo Bonzini perror("setitimer"); 85084682834SPaolo Bonzini fprintf(stderr, "Internal timer error: aborting\n"); 85184682834SPaolo Bonzini exit(1); 85284682834SPaolo Bonzini } 853db1a4972SPaolo Bonzini } 854db1a4972SPaolo Bonzini 855db1a4972SPaolo Bonzini static void unix_stop_timer(struct qemu_alarm_timer *t) 856db1a4972SPaolo Bonzini { 857db1a4972SPaolo Bonzini struct itimerval itv; 858db1a4972SPaolo Bonzini 859db1a4972SPaolo Bonzini memset(&itv, 0, sizeof(itv)); 860db1a4972SPaolo Bonzini setitimer(ITIMER_REAL, &itv, NULL); 861db1a4972SPaolo Bonzini } 862db1a4972SPaolo Bonzini 863db1a4972SPaolo Bonzini #endif /* !defined(_WIN32) */ 864db1a4972SPaolo Bonzini 865db1a4972SPaolo Bonzini 866db1a4972SPaolo Bonzini #ifdef _WIN32 867db1a4972SPaolo Bonzini 8682f9cba0cSStefan Weil static MMRESULT mm_timer; 86940f08e87SStefan Weil static TIMECAPS mm_tc; 8702f9cba0cSStefan Weil 8712f9cba0cSStefan Weil static void CALLBACK mm_alarm_handler(UINT uTimerID, UINT uMsg, 8722f9cba0cSStefan Weil DWORD_PTR dwUser, DWORD_PTR dw1, 8732f9cba0cSStefan Weil DWORD_PTR dw2) 8742f9cba0cSStefan Weil { 8752f9cba0cSStefan Weil struct qemu_alarm_timer *t = alarm_timer; 8762f9cba0cSStefan Weil if (!t) { 8772f9cba0cSStefan Weil return; 8782f9cba0cSStefan Weil } 8798205199dSStefan Weil t->expired = true; 8805e1ec7b2SStefan Weil t->pending = true; 8812f9cba0cSStefan Weil qemu_notify_event(); 8822f9cba0cSStefan Weil } 8832f9cba0cSStefan Weil 8842f9cba0cSStefan Weil static int mm_start_timer(struct qemu_alarm_timer *t) 8852f9cba0cSStefan Weil { 88640f08e87SStefan Weil timeGetDevCaps(&mm_tc, sizeof(mm_tc)); 8872f9cba0cSStefan Weil return 0; 8882f9cba0cSStefan Weil } 8892f9cba0cSStefan Weil 8902f9cba0cSStefan Weil static void mm_stop_timer(struct qemu_alarm_timer *t) 8912f9cba0cSStefan Weil { 8920727b867SPaolo Bonzini if (mm_timer) { 8932f9cba0cSStefan Weil timeKillEvent(mm_timer); 8940727b867SPaolo Bonzini } 8952f9cba0cSStefan Weil } 8962f9cba0cSStefan Weil 897f3fc6e2eSPaolo Bonzini static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta) 8982f9cba0cSStefan Weil { 8995bfb723fSStefano Stabellini int64_t nearest_delta_ms = delta / 1000000; 90040f08e87SStefan Weil if (nearest_delta_ms < mm_tc.wPeriodMin) { 90140f08e87SStefan Weil nearest_delta_ms = mm_tc.wPeriodMin; 90240f08e87SStefan Weil } else if (nearest_delta_ms > mm_tc.wPeriodMax) { 90340f08e87SStefan Weil nearest_delta_ms = mm_tc.wPeriodMax; 9045bfb723fSStefano Stabellini } 905f3fc6e2eSPaolo Bonzini 9060727b867SPaolo Bonzini if (mm_timer) { 907f3fc6e2eSPaolo Bonzini timeKillEvent(mm_timer); 9080727b867SPaolo Bonzini } 90940f08e87SStefan Weil mm_timer = timeSetEvent((UINT)nearest_delta_ms, 91040f08e87SStefan Weil mm_tc.wPeriodMin, 9112f9cba0cSStefan Weil mm_alarm_handler, 9122f9cba0cSStefan Weil (DWORD_PTR)t, 9132f9cba0cSStefan Weil TIME_ONESHOT | TIME_CALLBACK_FUNCTION); 9142f9cba0cSStefan Weil 9152f9cba0cSStefan Weil if (!mm_timer) { 91652ef651fSStefan Weil fprintf(stderr, "Failed to re-arm win32 alarm timer\n"); 91740f08e87SStefan Weil timeEndPeriod(mm_tc.wPeriodMin); 9182f9cba0cSStefan Weil exit(1); 9192f9cba0cSStefan Weil } 9202f9cba0cSStefan Weil } 9212f9cba0cSStefan Weil 922db1a4972SPaolo Bonzini static int win32_start_timer(struct qemu_alarm_timer *t) 923db1a4972SPaolo Bonzini { 92468c23e55SPaolo Bonzini HANDLE hTimer; 92568c23e55SPaolo Bonzini BOOLEAN success; 926db1a4972SPaolo Bonzini 92768c23e55SPaolo Bonzini /* If you call ChangeTimerQueueTimer on a one-shot timer (its period 92868c23e55SPaolo Bonzini is zero) that has already expired, the timer is not updated. Since 92968c23e55SPaolo Bonzini creating a new timer is relatively expensive, set a bogus one-hour 93068c23e55SPaolo Bonzini interval in the dynticks case. */ 93168c23e55SPaolo Bonzini success = CreateTimerQueueTimer(&hTimer, 93268c23e55SPaolo Bonzini NULL, 93368c23e55SPaolo Bonzini host_alarm_handler, 93468c23e55SPaolo Bonzini t, 93568c23e55SPaolo Bonzini 1, 9368205199dSStefan Weil 3600000, 93768c23e55SPaolo Bonzini WT_EXECUTEINTIMERTHREAD); 938db1a4972SPaolo Bonzini 93968c23e55SPaolo Bonzini if (!success) { 940db1a4972SPaolo Bonzini fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n", 941db1a4972SPaolo Bonzini GetLastError()); 942db1a4972SPaolo Bonzini return -1; 943db1a4972SPaolo Bonzini } 944db1a4972SPaolo Bonzini 945cd0544eeSStefan Weil t->timer = hTimer; 946db1a4972SPaolo Bonzini return 0; 947db1a4972SPaolo Bonzini } 948db1a4972SPaolo Bonzini 949db1a4972SPaolo Bonzini static void win32_stop_timer(struct qemu_alarm_timer *t) 950db1a4972SPaolo Bonzini { 951cd0544eeSStefan Weil HANDLE hTimer = t->timer; 952db1a4972SPaolo Bonzini 95368c23e55SPaolo Bonzini if (hTimer) { 95468c23e55SPaolo Bonzini DeleteTimerQueueTimer(NULL, hTimer, NULL); 95568c23e55SPaolo Bonzini } 956db1a4972SPaolo Bonzini } 957db1a4972SPaolo Bonzini 958f3fc6e2eSPaolo Bonzini static void win32_rearm_timer(struct qemu_alarm_timer *t, 959f3fc6e2eSPaolo Bonzini int64_t nearest_delta_ns) 960db1a4972SPaolo Bonzini { 961cd0544eeSStefan Weil HANDLE hTimer = t->timer; 9625bfb723fSStefano Stabellini int64_t nearest_delta_ms; 96368c23e55SPaolo Bonzini BOOLEAN success; 964db1a4972SPaolo Bonzini 9655bfb723fSStefano Stabellini nearest_delta_ms = nearest_delta_ns / 1000000; 966cfced5b2SPaolo Bonzini if (nearest_delta_ms < 1) { 967cfced5b2SPaolo Bonzini nearest_delta_ms = 1; 968cfced5b2SPaolo Bonzini } 9695bfb723fSStefano Stabellini /* ULONG_MAX can be 32 bit */ 9705bfb723fSStefano Stabellini if (nearest_delta_ms > ULONG_MAX) { 9715bfb723fSStefano Stabellini nearest_delta_ms = ULONG_MAX; 9725bfb723fSStefano Stabellini } 97368c23e55SPaolo Bonzini success = ChangeTimerQueueTimer(NULL, 97468c23e55SPaolo Bonzini hTimer, 9755bfb723fSStefano Stabellini (unsigned long) nearest_delta_ms, 97668c23e55SPaolo Bonzini 3600000); 977db1a4972SPaolo Bonzini 97868c23e55SPaolo Bonzini if (!success) { 97968c23e55SPaolo Bonzini fprintf(stderr, "Failed to rearm win32 alarm timer: %ld\n", 980db1a4972SPaolo Bonzini GetLastError()); 98168c23e55SPaolo Bonzini exit(-1); 982db1a4972SPaolo Bonzini } 98368c23e55SPaolo Bonzini 984db1a4972SPaolo Bonzini } 985db1a4972SPaolo Bonzini 986db1a4972SPaolo Bonzini #endif /* _WIN32 */ 987db1a4972SPaolo Bonzini 9884260a739SPaolo Bonzini static void quit_timers(void) 9894260a739SPaolo Bonzini { 9904260a739SPaolo Bonzini struct qemu_alarm_timer *t = alarm_timer; 9914260a739SPaolo Bonzini alarm_timer = NULL; 9924260a739SPaolo Bonzini t->stop(t); 9934260a739SPaolo Bonzini } 9944260a739SPaolo Bonzini 995253ecf83SStefan Weil #ifdef CONFIG_POSIX 996c8122c35SPaolo Bonzini static void reinit_timers(void) 997c8122c35SPaolo Bonzini { 998c8122c35SPaolo Bonzini struct qemu_alarm_timer *t = alarm_timer; 999c8122c35SPaolo Bonzini t->stop(t); 1000c8122c35SPaolo Bonzini if (t->start(t)) { 1001c8122c35SPaolo Bonzini fprintf(stderr, "Internal timer error: aborting\n"); 1002c8122c35SPaolo Bonzini exit(1); 1003c8122c35SPaolo Bonzini } 1004c8122c35SPaolo Bonzini qemu_rearm_alarm_timer(t); 1005c8122c35SPaolo Bonzini } 1006253ecf83SStefan Weil #endif /* CONFIG_POSIX */ 1007c8122c35SPaolo Bonzini 1008db1a4972SPaolo Bonzini int init_timer_alarm(void) 1009db1a4972SPaolo Bonzini { 1010db1a4972SPaolo Bonzini struct qemu_alarm_timer *t = NULL; 1011db1a4972SPaolo Bonzini int i, err = -1; 1012db1a4972SPaolo Bonzini 1013744ca8e3SPaolo Bonzini if (alarm_timer) { 1014744ca8e3SPaolo Bonzini return 0; 1015744ca8e3SPaolo Bonzini } 1016744ca8e3SPaolo Bonzini 1017db1a4972SPaolo Bonzini for (i = 0; alarm_timers[i].name; i++) { 1018db1a4972SPaolo Bonzini t = &alarm_timers[i]; 1019db1a4972SPaolo Bonzini 1020db1a4972SPaolo Bonzini err = t->start(t); 1021db1a4972SPaolo Bonzini if (!err) 1022db1a4972SPaolo Bonzini break; 1023db1a4972SPaolo Bonzini } 1024db1a4972SPaolo Bonzini 1025db1a4972SPaolo Bonzini if (err) { 1026db1a4972SPaolo Bonzini err = -ENOENT; 1027db1a4972SPaolo Bonzini goto fail; 1028db1a4972SPaolo Bonzini } 1029db1a4972SPaolo Bonzini 10304260a739SPaolo Bonzini atexit(quit_timers); 1031c8122c35SPaolo Bonzini #ifdef CONFIG_POSIX 1032c8122c35SPaolo Bonzini pthread_atfork(NULL, NULL, reinit_timers); 1033c8122c35SPaolo Bonzini #endif 1034db1a4972SPaolo Bonzini alarm_timer = t; 1035db1a4972SPaolo Bonzini return 0; 1036db1a4972SPaolo Bonzini 1037db1a4972SPaolo Bonzini fail: 1038db1a4972SPaolo Bonzini return err; 1039db1a4972SPaolo Bonzini } 1040db1a4972SPaolo Bonzini 1041