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