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 QLIST_HEAD(, QEMUTimerList) timerlists; 49 50 NotifierList reset_notifiers; 51 int64_t last; 52 53 QEMUClockType type; 54 bool enabled; 55 } QEMUClock; 56 57 QEMUTimerListGroup main_loop_tlg; 58 QEMUClock qemu_clocks[QEMU_CLOCK_MAX]; 59 60 /* A QEMUTimerList is a list of timers attached to a clock. More 61 * than one QEMUTimerList can be attached to each clock, for instance 62 * used by different AioContexts / threads. Each clock also has 63 * a list of the QEMUTimerLists associated with it, in order that 64 * reenabling the clock can call all the notifiers. 65 */ 66 67 struct QEMUTimerList { 68 QEMUClock *clock; 69 QEMUTimer *active_timers; 70 QLIST_ENTRY(QEMUTimerList) list; 71 QEMUTimerListNotifyCB *notify_cb; 72 void *notify_opaque; 73 }; 74 75 /** 76 * qemu_clock_ptr: 77 * @type: type of clock 78 * 79 * Translate a clock type into a pointer to QEMUClock object. 80 * 81 * Returns: a pointer to the QEMUClock object 82 */ 83 static inline QEMUClock *qemu_clock_ptr(QEMUClockType type) 84 { 85 return &qemu_clocks[type]; 86 } 87 88 static bool timer_expired_ns(QEMUTimer *timer_head, int64_t current_time) 89 { 90 return timer_head && (timer_head->expire_time <= current_time); 91 } 92 93 QEMUTimerList *timerlist_new(QEMUClockType type, 94 QEMUTimerListNotifyCB *cb, 95 void *opaque) 96 { 97 QEMUTimerList *timer_list; 98 QEMUClock *clock = qemu_clock_ptr(type); 99 100 timer_list = g_malloc0(sizeof(QEMUTimerList)); 101 timer_list->clock = clock; 102 timer_list->notify_cb = cb; 103 timer_list->notify_opaque = opaque; 104 QLIST_INSERT_HEAD(&clock->timerlists, timer_list, list); 105 return timer_list; 106 } 107 108 void timerlist_free(QEMUTimerList *timer_list) 109 { 110 assert(!timerlist_has_timers(timer_list)); 111 if (timer_list->clock) { 112 QLIST_REMOVE(timer_list, list); 113 } 114 g_free(timer_list); 115 } 116 117 static void qemu_clock_init(QEMUClockType type) 118 { 119 QEMUClock *clock = qemu_clock_ptr(type); 120 121 clock->type = type; 122 clock->enabled = true; 123 clock->last = INT64_MIN; 124 QLIST_INIT(&clock->timerlists); 125 notifier_list_init(&clock->reset_notifiers); 126 main_loop_tlg.tl[type] = timerlist_new(type, NULL, NULL); 127 } 128 129 bool qemu_clock_use_for_deadline(QEMUClockType type) 130 { 131 return !(use_icount && (type == QEMU_CLOCK_VIRTUAL)); 132 } 133 134 void qemu_clock_notify(QEMUClockType type) 135 { 136 QEMUTimerList *timer_list; 137 QEMUClock *clock = qemu_clock_ptr(type); 138 QLIST_FOREACH(timer_list, &clock->timerlists, list) { 139 timerlist_notify(timer_list); 140 } 141 } 142 143 void qemu_clock_enable(QEMUClockType type, bool enabled) 144 { 145 QEMUClock *clock = qemu_clock_ptr(type); 146 bool old = clock->enabled; 147 clock->enabled = enabled; 148 if (enabled && !old) { 149 qemu_clock_notify(type); 150 } 151 } 152 153 bool timerlist_has_timers(QEMUTimerList *timer_list) 154 { 155 return !!timer_list->active_timers; 156 } 157 158 bool qemu_clock_has_timers(QEMUClockType type) 159 { 160 return timerlist_has_timers( 161 main_loop_tlg.tl[type]); 162 } 163 164 bool timerlist_expired(QEMUTimerList *timer_list) 165 { 166 return (timer_list->active_timers && 167 timer_list->active_timers->expire_time < 168 qemu_clock_get_ns(timer_list->clock->type)); 169 } 170 171 bool qemu_clock_expired(QEMUClockType type) 172 { 173 return timerlist_expired( 174 main_loop_tlg.tl[type]); 175 } 176 177 /* 178 * As above, but return -1 for no deadline, and do not cap to 2^32 179 * as we know the result is always positive. 180 */ 181 182 int64_t timerlist_deadline_ns(QEMUTimerList *timer_list) 183 { 184 int64_t delta; 185 186 if (!timer_list->clock->enabled || !timer_list->active_timers) { 187 return -1; 188 } 189 190 delta = timer_list->active_timers->expire_time - 191 qemu_clock_get_ns(timer_list->clock->type); 192 193 if (delta <= 0) { 194 return 0; 195 } 196 197 return delta; 198 } 199 200 /* Calculate the soonest deadline across all timerlists attached 201 * to the clock. This is used for the icount timeout so we 202 * ignore whether or not the clock should be used in deadline 203 * calculations. 204 */ 205 int64_t qemu_clock_deadline_ns_all(QEMUClockType type) 206 { 207 int64_t deadline = -1; 208 QEMUTimerList *timer_list; 209 QEMUClock *clock = qemu_clock_ptr(type); 210 QLIST_FOREACH(timer_list, &clock->timerlists, list) { 211 deadline = qemu_soonest_timeout(deadline, 212 timerlist_deadline_ns(timer_list)); 213 } 214 return deadline; 215 } 216 217 QEMUClockType timerlist_get_clock(QEMUTimerList *timer_list) 218 { 219 return timer_list->clock->type; 220 } 221 222 QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClockType type) 223 { 224 return main_loop_tlg.tl[type]; 225 } 226 227 void timerlist_notify(QEMUTimerList *timer_list) 228 { 229 if (timer_list->notify_cb) { 230 timer_list->notify_cb(timer_list->notify_opaque); 231 } else { 232 qemu_notify_event(); 233 } 234 } 235 236 /* Transition function to convert a nanosecond timeout to ms 237 * This is used where a system does not support ppoll 238 */ 239 int qemu_timeout_ns_to_ms(int64_t ns) 240 { 241 int64_t ms; 242 if (ns < 0) { 243 return -1; 244 } 245 246 if (!ns) { 247 return 0; 248 } 249 250 /* Always round up, because it's better to wait too long than to wait too 251 * little and effectively busy-wait 252 */ 253 ms = (ns + SCALE_MS - 1) / SCALE_MS; 254 255 /* To avoid overflow problems, limit this to 2^31, i.e. approx 25 days */ 256 if (ms > (int64_t) INT32_MAX) { 257 ms = INT32_MAX; 258 } 259 260 return (int) ms; 261 } 262 263 264 /* qemu implementation of g_poll which uses a nanosecond timeout but is 265 * otherwise identical to g_poll 266 */ 267 int qemu_poll_ns(GPollFD *fds, guint nfds, int64_t timeout) 268 { 269 #ifdef CONFIG_PPOLL 270 if (timeout < 0) { 271 return ppoll((struct pollfd *)fds, nfds, NULL, NULL); 272 } else { 273 struct timespec ts; 274 ts.tv_sec = timeout / 1000000000LL; 275 ts.tv_nsec = timeout % 1000000000LL; 276 return ppoll((struct pollfd *)fds, nfds, &ts, NULL); 277 } 278 #else 279 return g_poll(fds, nfds, qemu_timeout_ns_to_ms(timeout)); 280 #endif 281 } 282 283 284 void timer_init(QEMUTimer *ts, 285 QEMUTimerList *timer_list, int scale, 286 QEMUTimerCB *cb, void *opaque) 287 { 288 ts->timer_list = timer_list; 289 ts->cb = cb; 290 ts->opaque = opaque; 291 ts->scale = scale; 292 } 293 294 void timer_free(QEMUTimer *ts) 295 { 296 g_free(ts); 297 } 298 299 /* stop a timer, but do not dealloc it */ 300 void timer_del(QEMUTimer *ts) 301 { 302 QEMUTimer **pt, *t; 303 304 /* NOTE: this code must be signal safe because 305 timer_expired() can be called from a signal. */ 306 pt = &ts->timer_list->active_timers; 307 for(;;) { 308 t = *pt; 309 if (!t) 310 break; 311 if (t == ts) { 312 *pt = t->next; 313 break; 314 } 315 pt = &t->next; 316 } 317 } 318 319 /* modify the current timer so that it will be fired when current_time 320 >= expire_time. The corresponding callback will be called. */ 321 void timer_mod_ns(QEMUTimer *ts, int64_t expire_time) 322 { 323 QEMUTimer **pt, *t; 324 325 timer_del(ts); 326 327 /* add the timer in the sorted list */ 328 /* NOTE: this code must be signal safe because 329 timer_expired() can be called from a signal. */ 330 pt = &ts->timer_list->active_timers; 331 for(;;) { 332 t = *pt; 333 if (!timer_expired_ns(t, expire_time)) { 334 break; 335 } 336 pt = &t->next; 337 } 338 ts->expire_time = expire_time; 339 ts->next = *pt; 340 *pt = ts; 341 342 /* Rearm if necessary */ 343 if (pt == &ts->timer_list->active_timers) { 344 /* Interrupt execution to force deadline recalculation. */ 345 qemu_clock_warp(ts->timer_list->clock->type); 346 timerlist_notify(ts->timer_list); 347 } 348 } 349 350 void timer_mod(QEMUTimer *ts, int64_t expire_time) 351 { 352 timer_mod_ns(ts, expire_time * ts->scale); 353 } 354 355 bool timer_pending(QEMUTimer *ts) 356 { 357 QEMUTimer *t; 358 for (t = ts->timer_list->active_timers; t != NULL; t = t->next) { 359 if (t == ts) { 360 return true; 361 } 362 } 363 return false; 364 } 365 366 bool timer_expired(QEMUTimer *timer_head, int64_t current_time) 367 { 368 return timer_expired_ns(timer_head, current_time * timer_head->scale); 369 } 370 371 bool timerlist_run_timers(QEMUTimerList *timer_list) 372 { 373 QEMUTimer *ts; 374 int64_t current_time; 375 bool progress = false; 376 377 if (!timer_list->clock->enabled) { 378 return progress; 379 } 380 381 current_time = qemu_clock_get_ns(timer_list->clock->type); 382 for(;;) { 383 ts = timer_list->active_timers; 384 if (!timer_expired_ns(ts, current_time)) { 385 break; 386 } 387 /* remove timer from the list before calling the callback */ 388 timer_list->active_timers = ts->next; 389 ts->next = NULL; 390 391 /* run the callback (the timer list can be modified) */ 392 ts->cb(ts->opaque); 393 progress = true; 394 } 395 return progress; 396 } 397 398 bool qemu_clock_run_timers(QEMUClockType type) 399 { 400 return timerlist_run_timers(main_loop_tlg.tl[type]); 401 } 402 403 void timerlistgroup_init(QEMUTimerListGroup *tlg, 404 QEMUTimerListNotifyCB *cb, void *opaque) 405 { 406 QEMUClockType type; 407 for (type = 0; type < QEMU_CLOCK_MAX; type++) { 408 tlg->tl[type] = timerlist_new(type, cb, opaque); 409 } 410 } 411 412 void timerlistgroup_deinit(QEMUTimerListGroup *tlg) 413 { 414 QEMUClockType type; 415 for (type = 0; type < QEMU_CLOCK_MAX; type++) { 416 timerlist_free(tlg->tl[type]); 417 } 418 } 419 420 bool timerlistgroup_run_timers(QEMUTimerListGroup *tlg) 421 { 422 QEMUClockType type; 423 bool progress = false; 424 for (type = 0; type < QEMU_CLOCK_MAX; type++) { 425 progress |= timerlist_run_timers(tlg->tl[type]); 426 } 427 return progress; 428 } 429 430 int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg) 431 { 432 int64_t deadline = -1; 433 QEMUClockType type; 434 for (type = 0; type < QEMU_CLOCK_MAX; type++) { 435 if (qemu_clock_use_for_deadline(tlg->tl[type]->clock->type)) { 436 deadline = qemu_soonest_timeout(deadline, 437 timerlist_deadline_ns( 438 tlg->tl[type])); 439 } 440 } 441 return deadline; 442 } 443 444 int64_t qemu_clock_get_ns(QEMUClockType type) 445 { 446 int64_t now, last; 447 QEMUClock *clock = qemu_clock_ptr(type); 448 449 switch (type) { 450 case QEMU_CLOCK_REALTIME: 451 return get_clock(); 452 default: 453 case QEMU_CLOCK_VIRTUAL: 454 if (use_icount) { 455 return cpu_get_icount(); 456 } else { 457 return cpu_get_clock(); 458 } 459 case QEMU_CLOCK_HOST: 460 now = get_clock_realtime(); 461 last = clock->last; 462 clock->last = now; 463 if (now < last) { 464 notifier_list_notify(&clock->reset_notifiers, &now); 465 } 466 return now; 467 } 468 } 469 470 void qemu_clock_register_reset_notifier(QEMUClockType type, 471 Notifier *notifier) 472 { 473 QEMUClock *clock = qemu_clock_ptr(type); 474 notifier_list_add(&clock->reset_notifiers, notifier); 475 } 476 477 void qemu_clock_unregister_reset_notifier(QEMUClockType type, 478 Notifier *notifier) 479 { 480 notifier_remove(notifier); 481 } 482 483 void init_clocks(void) 484 { 485 QEMUClockType type; 486 for (type = 0; type < QEMU_CLOCK_MAX; type++) { 487 qemu_clock_init(type); 488 } 489 490 #ifdef CONFIG_PRCTL_PR_SET_TIMERSLACK 491 prctl(PR_SET_TIMERSLACK, 1, 0, 0, 0); 492 #endif 493 } 494 495 uint64_t timer_expire_time_ns(QEMUTimer *ts) 496 { 497 return timer_pending(ts) ? ts->expire_time : -1; 498 } 499 500 bool qemu_clock_run_all_timers(void) 501 { 502 bool progress = false; 503 QEMUClockType type; 504 505 for (type = 0; type < QEMU_CLOCK_MAX; type++) { 506 progress |= qemu_clock_run_timers(type); 507 } 508 509 return progress; 510 } 511