1/* 2 * QEMU System Emulator 3 * 4 * Copyright (c) 2003-2008 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24 25#include "sysemu/sysemu.h" 26#include "monitor/monitor.h" 27#include "ui/console.h" 28 29#include "hw/hw.h" 30 31#include "qemu/thread.h" 32#include "qemu/timer.h" 33#ifdef CONFIG_POSIX 34#include <pthread.h> 35#endif 36 37#ifdef CONFIG_PPOLL 38#include <poll.h> 39#endif 40 41#ifdef CONFIG_PRCTL_PR_SET_TIMERSLACK 42#include <sys/prctl.h> 43#endif 44 45/***********************************************************/ 46/* timers */ 47 48typedef struct QEMUClock { 49 /* We rely on BQL to protect the timerlists */ 50 QLIST_HEAD(, QEMUTimerList) timerlists; 51 52 NotifierList reset_notifiers; 53 int64_t last; 54 55 QEMUClockType type; 56 bool enabled; 57} QEMUClock; 58 59QEMUTimerListGroup main_loop_tlg; 60QEMUClock qemu_clocks[QEMU_CLOCK_MAX]; 61 62/* A QEMUTimerList is a list of timers attached to a clock. More 63 * than one QEMUTimerList can be attached to each clock, for instance 64 * used by different AioContexts / threads. Each clock also has 65 * a list of the QEMUTimerLists associated with it, in order that 66 * reenabling the clock can call all the notifiers. 67 */ 68 69struct QEMUTimerList { 70 QEMUClock *clock; 71 QemuMutex active_timers_lock; 72 QEMUTimer *active_timers; 73 QLIST_ENTRY(QEMUTimerList) list; 74 QEMUTimerListNotifyCB *notify_cb; 75 void *notify_opaque; 76 77 /* lightweight method to mark the end of timerlist's running */ 78 QemuEvent timers_done_ev; 79}; 80 81/** 82 * qemu_clock_ptr: 83 * @type: type of clock 84 * 85 * Translate a clock type into a pointer to QEMUClock object. 86 * 87 * Returns: a pointer to the QEMUClock object 88 */ 89static inline QEMUClock *qemu_clock_ptr(QEMUClockType type) 90{ 91 return &qemu_clocks[type]; 92} 93 94static bool timer_expired_ns(QEMUTimer *timer_head, int64_t current_time) 95{ 96 return timer_head && (timer_head->expire_time <= current_time); 97} 98 99QEMUTimerList *timerlist_new(QEMUClockType type, 100 QEMUTimerListNotifyCB *cb, 101 void *opaque) 102{ 103 QEMUTimerList *timer_list; 104 QEMUClock *clock = qemu_clock_ptr(type); 105 106 timer_list = g_malloc0(sizeof(QEMUTimerList)); 107 qemu_event_init(&timer_list->timers_done_ev, false); 108 timer_list->clock = clock; 109 timer_list->notify_cb = cb; 110 timer_list->notify_opaque = opaque; 111 qemu_mutex_init(&timer_list->active_timers_lock); 112 QLIST_INSERT_HEAD(&clock->timerlists, timer_list, list); 113 return timer_list; 114} 115 116void timerlist_free(QEMUTimerList *timer_list) 117{ 118 assert(!timerlist_has_timers(timer_list)); 119 if (timer_list->clock) { 120 QLIST_REMOVE(timer_list, list); 121 } 122 qemu_mutex_destroy(&timer_list->active_timers_lock); 123 g_free(timer_list); 124} 125 126static void qemu_clock_init(QEMUClockType type) 127{ 128 QEMUClock *clock = qemu_clock_ptr(type); 129 130 clock->type = type; 131 clock->enabled = true; 132 clock->last = INT64_MIN; 133 QLIST_INIT(&clock->timerlists); 134 notifier_list_init(&clock->reset_notifiers); 135 main_loop_tlg.tl[type] = timerlist_new(type, NULL, NULL); 136} 137 138bool qemu_clock_use_for_deadline(QEMUClockType type) 139{ 140 return !(use_icount && (type == QEMU_CLOCK_VIRTUAL)); 141} 142 143void qemu_clock_notify(QEMUClockType type) 144{ 145 QEMUTimerList *timer_list; 146 QEMUClock *clock = qemu_clock_ptr(type); 147 QLIST_FOREACH(timer_list, &clock->timerlists, list) { 148 timerlist_notify(timer_list); 149 } 150} 151 152/* Disabling the clock will wait for related timerlists to stop 153 * executing qemu_run_timers. Thus, this functions should not 154 * be used from the callback of a timer that is based on @clock. 155 * Doing so would cause a deadlock. 156 * 157 * Caller should hold BQL. 158 */ 159void qemu_clock_enable(QEMUClockType type, bool enabled) 160{ 161 QEMUClock *clock = qemu_clock_ptr(type); 162 QEMUTimerList *tl; 163 bool old = clock->enabled; 164 clock->enabled = enabled; 165 if (enabled && !old) { 166 qemu_clock_notify(type); 167 } else if (!enabled && old) { 168 QLIST_FOREACH(tl, &clock->timerlists, list) { 169 qemu_event_wait(&tl->timers_done_ev); 170 } 171 } 172} 173 174bool timerlist_has_timers(QEMUTimerList *timer_list) 175{ 176 return !!timer_list->active_timers; 177} 178 179bool qemu_clock_has_timers(QEMUClockType type) 180{ 181 return timerlist_has_timers( 182 main_loop_tlg.tl[type]); 183} 184 185bool timerlist_expired(QEMUTimerList *timer_list) 186{ 187 int64_t expire_time; 188 189 qemu_mutex_lock(&timer_list->active_timers_lock); 190 if (!timer_list->active_timers) { 191 qemu_mutex_unlock(&timer_list->active_timers_lock); 192 return false; 193 } 194 expire_time = timer_list->active_timers->expire_time; 195 qemu_mutex_unlock(&timer_list->active_timers_lock); 196 197 return expire_time < qemu_clock_get_ns(timer_list->clock->type); 198} 199 200bool qemu_clock_expired(QEMUClockType type) 201{ 202 return timerlist_expired( 203 main_loop_tlg.tl[type]); 204} 205 206/* 207 * As above, but return -1 for no deadline, and do not cap to 2^32 208 * as we know the result is always positive. 209 */ 210 211int64_t timerlist_deadline_ns(QEMUTimerList *timer_list) 212{ 213 int64_t delta; 214 int64_t expire_time; 215 216 if (!timer_list->clock->enabled) { 217 return -1; 218 } 219 220 /* The active timers list may be modified before the caller uses our return 221 * value but ->notify_cb() is called when the deadline changes. Therefore 222 * the caller should notice the change and there is no race condition. 223 */ 224 qemu_mutex_lock(&timer_list->active_timers_lock); 225 if (!timer_list->active_timers) { 226 qemu_mutex_unlock(&timer_list->active_timers_lock); 227 return -1; 228 } 229 expire_time = timer_list->active_timers->expire_time; 230 qemu_mutex_unlock(&timer_list->active_timers_lock); 231 232 delta = expire_time - qemu_clock_get_ns(timer_list->clock->type); 233 234 if (delta <= 0) { 235 return 0; 236 } 237 238 return delta; 239} 240 241/* Calculate the soonest deadline across all timerlists attached 242 * to the clock. This is used for the icount timeout so we 243 * ignore whether or not the clock should be used in deadline 244 * calculations. 245 */ 246int64_t qemu_clock_deadline_ns_all(QEMUClockType type) 247{ 248 int64_t deadline = -1; 249 QEMUTimerList *timer_list; 250 QEMUClock *clock = qemu_clock_ptr(type); 251 QLIST_FOREACH(timer_list, &clock->timerlists, list) { 252 deadline = qemu_soonest_timeout(deadline, 253 timerlist_deadline_ns(timer_list)); 254 } 255 return deadline; 256} 257 258QEMUClockType timerlist_get_clock(QEMUTimerList *timer_list) 259{ 260 return timer_list->clock->type; 261} 262 263QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClockType type) 264{ 265 return main_loop_tlg.tl[type]; 266} 267 268void timerlist_notify(QEMUTimerList *timer_list) 269{ 270 if (timer_list->notify_cb) { 271 timer_list->notify_cb(timer_list->notify_opaque); 272 } else { 273 qemu_notify_event(); 274 } 275} 276 277/* Transition function to convert a nanosecond timeout to ms 278 * This is used where a system does not support ppoll 279 */ 280int qemu_timeout_ns_to_ms(int64_t ns) 281{ 282 int64_t ms; 283 if (ns < 0) { 284 return -1; 285 } 286 287 if (!ns) { 288 return 0; 289 } 290 291 /* Always round up, because it's better to wait too long than to wait too 292 * little and effectively busy-wait 293 */ 294 ms = (ns + SCALE_MS - 1) / SCALE_MS; 295 296 /* To avoid overflow problems, limit this to 2^31, i.e. approx 25 days */ 297 if (ms > (int64_t) INT32_MAX) { 298 ms = INT32_MAX; 299 } 300 301 return (int) ms; 302} 303 304#ifndef CONFIG_ANDROID // TODO(digit): Implement g_poll() 305/* qemu implementation of g_poll which uses a nanosecond timeout but is 306 * otherwise identical to g_poll 307 */ 308int qemu_poll_ns(GPollFD *fds, guint nfds, int64_t timeout) 309{ 310#ifdef CONFIG_PPOLL 311 if (timeout < 0) { 312 return ppoll((struct pollfd *)fds, nfds, NULL, NULL); 313 } else { 314 struct timespec ts; 315 ts.tv_sec = timeout / 1000000000LL; 316 ts.tv_nsec = timeout % 1000000000LL; 317 return ppoll((struct pollfd *)fds, nfds, &ts, NULL); 318 } 319#else 320 return g_poll(fds, nfds, qemu_timeout_ns_to_ms(timeout)); 321#endif 322} 323#endif // !CONFIG_ANDROID 324 325void timer_init(QEMUTimer *ts, 326 QEMUTimerList *timer_list, int scale, 327 QEMUTimerCB *cb, void *opaque) 328{ 329 ts->timer_list = timer_list; 330 ts->cb = cb; 331 ts->opaque = opaque; 332 ts->scale = scale; 333 ts->expire_time = -1; 334} 335 336void timer_free(QEMUTimer *ts) 337{ 338 g_free(ts); 339} 340 341static void timer_del_locked(QEMUTimerList *timer_list, QEMUTimer *ts) 342{ 343 QEMUTimer **pt, *t; 344 345 ts->expire_time = -1; 346 pt = &timer_list->active_timers; 347 for(;;) { 348 t = *pt; 349 if (!t) 350 break; 351 if (t == ts) { 352 *pt = t->next; 353 break; 354 } 355 pt = &t->next; 356 } 357} 358 359static bool timer_mod_ns_locked(QEMUTimerList *timer_list, 360 QEMUTimer *ts, int64_t expire_time) 361{ 362 QEMUTimer **pt, *t; 363 364 /* add the timer in the sorted list */ 365 pt = &timer_list->active_timers; 366 for (;;) { 367 t = *pt; 368 if (!timer_expired_ns(t, expire_time)) { 369 break; 370 } 371 pt = &t->next; 372 } 373 ts->expire_time = MAX(expire_time, 0); 374 ts->next = *pt; 375 *pt = ts; 376 377 return pt == &timer_list->active_timers; 378} 379 380static void timerlist_rearm(QEMUTimerList *timer_list) 381{ 382 /* Interrupt execution to force deadline recalculation. */ 383 qemu_clock_warp(timer_list->clock->type); 384 timerlist_notify(timer_list); 385} 386 387/* stop a timer, but do not dealloc it */ 388void timer_del(QEMUTimer *ts) 389{ 390 QEMUTimerList *timer_list = ts->timer_list; 391 392 qemu_mutex_lock(&timer_list->active_timers_lock); 393 timer_del_locked(timer_list, ts); 394 qemu_mutex_unlock(&timer_list->active_timers_lock); 395} 396 397/* modify the current timer so that it will be fired when current_time 398 >= expire_time. The corresponding callback will be called. */ 399void timer_mod_ns(QEMUTimer *ts, int64_t expire_time) 400{ 401 QEMUTimerList *timer_list = ts->timer_list; 402 bool rearm; 403 404 qemu_mutex_lock(&timer_list->active_timers_lock); 405 timer_del_locked(timer_list, ts); 406 rearm = timer_mod_ns_locked(timer_list, ts, expire_time); 407 qemu_mutex_unlock(&timer_list->active_timers_lock); 408 409 if (rearm) { 410 timerlist_rearm(timer_list); 411 } 412} 413 414/* modify the current timer so that it will be fired when current_time 415 >= expire_time or the current deadline, whichever comes earlier. 416 The corresponding callback will be called. */ 417void timer_mod_anticipate_ns(QEMUTimer *ts, int64_t expire_time) 418{ 419 QEMUTimerList *timer_list = ts->timer_list; 420 bool rearm; 421 422 qemu_mutex_lock(&timer_list->active_timers_lock); 423 if (ts->expire_time == -1 || ts->expire_time > expire_time) { 424 if (ts->expire_time != -1) { 425 timer_del_locked(timer_list, ts); 426 } 427 rearm = timer_mod_ns_locked(timer_list, ts, expire_time); 428 } else { 429 rearm = false; 430 } 431 qemu_mutex_unlock(&timer_list->active_timers_lock); 432 433 if (rearm) { 434 timerlist_rearm(timer_list); 435 } 436} 437 438void timer_mod(QEMUTimer *ts, int64_t expire_time) 439{ 440 timer_mod_ns(ts, expire_time * ts->scale); 441} 442 443void timer_mod_anticipate(QEMUTimer *ts, int64_t expire_time) 444{ 445 timer_mod_anticipate_ns(ts, expire_time * ts->scale); 446} 447 448bool timer_pending(QEMUTimer *ts) 449{ 450 return ts->expire_time >= 0; 451} 452 453bool timer_expired(QEMUTimer *timer_head, int64_t current_time) 454{ 455 return timer_expired_ns(timer_head, current_time * timer_head->scale); 456} 457 458bool timerlist_run_timers(QEMUTimerList *timer_list) 459{ 460 QEMUTimer *ts; 461 int64_t current_time; 462 bool progress = false; 463 QEMUTimerCB *cb; 464 void *opaque; 465 466 qemu_event_reset(&timer_list->timers_done_ev); 467 if (!timer_list->clock->enabled) { 468 goto out; 469 } 470 471 current_time = qemu_clock_get_ns(timer_list->clock->type); 472 for(;;) { 473 qemu_mutex_lock(&timer_list->active_timers_lock); 474 ts = timer_list->active_timers; 475 if (!timer_expired_ns(ts, current_time)) { 476 qemu_mutex_unlock(&timer_list->active_timers_lock); 477 break; 478 } 479 480 /* remove timer from the list before calling the callback */ 481 timer_list->active_timers = ts->next; 482 ts->next = NULL; 483 ts->expire_time = -1; 484 cb = ts->cb; 485 opaque = ts->opaque; 486 qemu_mutex_unlock(&timer_list->active_timers_lock); 487 488 /* run the callback (the timer list can be modified) */ 489 cb(opaque); 490 progress = true; 491 } 492 493out: 494 qemu_event_set(&timer_list->timers_done_ev); 495 return progress; 496} 497 498bool qemu_clock_run_timers(QEMUClockType type) 499{ 500 return timerlist_run_timers(main_loop_tlg.tl[type]); 501} 502 503void timerlistgroup_init(QEMUTimerListGroup *tlg, 504 QEMUTimerListNotifyCB *cb, void *opaque) 505{ 506 QEMUClockType type; 507 for (type = 0; type < QEMU_CLOCK_MAX; type++) { 508 tlg->tl[type] = timerlist_new(type, cb, opaque); 509 } 510} 511 512void timerlistgroup_deinit(QEMUTimerListGroup *tlg) 513{ 514 QEMUClockType type; 515 for (type = 0; type < QEMU_CLOCK_MAX; type++) { 516 timerlist_free(tlg->tl[type]); 517 } 518} 519 520bool timerlistgroup_run_timers(QEMUTimerListGroup *tlg) 521{ 522 QEMUClockType type; 523 bool progress = false; 524 for (type = 0; type < QEMU_CLOCK_MAX; type++) { 525 progress |= timerlist_run_timers(tlg->tl[type]); 526 } 527 return progress; 528} 529 530int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg) 531{ 532 int64_t deadline = -1; 533 QEMUClockType type; 534 for (type = 0; type < QEMU_CLOCK_MAX; type++) { 535 if (qemu_clock_use_for_deadline(tlg->tl[type]->clock->type)) { 536 deadline = qemu_soonest_timeout(deadline, 537 timerlist_deadline_ns( 538 tlg->tl[type])); 539 } 540 } 541 return deadline; 542} 543 544int64_t qemu_clock_get_ns(QEMUClockType type) 545{ 546 int64_t now, last; 547 QEMUClock *clock = qemu_clock_ptr(type); 548 549 switch (type) { 550 case QEMU_CLOCK_REALTIME: 551 return get_clock(); 552 default: 553 case QEMU_CLOCK_VIRTUAL: 554 if (use_icount) { 555 return cpu_get_icount(); 556 } else { 557 return cpu_get_clock(); 558 } 559 case QEMU_CLOCK_HOST: 560 now = get_clock_realtime(); 561 last = clock->last; 562 clock->last = now; 563 if (now < last) { 564 notifier_list_notify(&clock->reset_notifiers, &now); 565 } 566 return now; 567 } 568} 569 570void qemu_clock_register_reset_notifier(QEMUClockType type, 571 Notifier *notifier) 572{ 573 QEMUClock *clock = qemu_clock_ptr(type); 574 notifier_list_add(&clock->reset_notifiers, notifier); 575} 576 577void qemu_clock_unregister_reset_notifier(QEMUClockType type, 578 Notifier *notifier) 579{ 580 notifier_remove(notifier); 581} 582 583void init_clocks(void) 584{ 585 QEMUClockType type; 586 for (type = 0; type < QEMU_CLOCK_MAX; type++) { 587 qemu_clock_init(type); 588 } 589 590#ifdef CONFIG_PRCTL_PR_SET_TIMERSLACK 591 prctl(PR_SET_TIMERSLACK, 1, 0, 0, 0); 592#endif 593} 594 595uint64_t timer_expire_time_ns(QEMUTimer *ts) 596{ 597 return timer_pending(ts) ? ts->expire_time : -1; 598} 599 600bool qemu_clock_run_all_timers(void) 601{ 602 bool progress = false; 603 QEMUClockType type; 604 605 for (type = 0; type < QEMU_CLOCK_MAX; type++) { 606 progress |= qemu_clock_run_timers(type); 607 } 608 609 return progress; 610} 611