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 pt = &ts->timer_list->active_timers; 305 for(;;) { 306 t = *pt; 307 if (!t) 308 break; 309 if (t == ts) { 310 *pt = t->next; 311 break; 312 } 313 pt = &t->next; 314 } 315 } 316 317 /* modify the current timer so that it will be fired when current_time 318 >= expire_time. The corresponding callback will be called. */ 319 void timer_mod_ns(QEMUTimer *ts, int64_t expire_time) 320 { 321 QEMUTimer **pt, *t; 322 323 timer_del(ts); 324 325 /* add the timer in the sorted list */ 326 pt = &ts->timer_list->active_timers; 327 for(;;) { 328 t = *pt; 329 if (!timer_expired_ns(t, expire_time)) { 330 break; 331 } 332 pt = &t->next; 333 } 334 ts->expire_time = expire_time; 335 ts->next = *pt; 336 *pt = ts; 337 338 /* Rearm if necessary */ 339 if (pt == &ts->timer_list->active_timers) { 340 /* Interrupt execution to force deadline recalculation. */ 341 qemu_clock_warp(ts->timer_list->clock->type); 342 timerlist_notify(ts->timer_list); 343 } 344 } 345 346 void timer_mod(QEMUTimer *ts, int64_t expire_time) 347 { 348 timer_mod_ns(ts, expire_time * ts->scale); 349 } 350 351 bool timer_pending(QEMUTimer *ts) 352 { 353 QEMUTimer *t; 354 for (t = ts->timer_list->active_timers; t != NULL; t = t->next) { 355 if (t == ts) { 356 return true; 357 } 358 } 359 return false; 360 } 361 362 bool timer_expired(QEMUTimer *timer_head, int64_t current_time) 363 { 364 return timer_expired_ns(timer_head, current_time * timer_head->scale); 365 } 366 367 bool timerlist_run_timers(QEMUTimerList *timer_list) 368 { 369 QEMUTimer *ts; 370 int64_t current_time; 371 bool progress = false; 372 373 if (!timer_list->clock->enabled) { 374 return progress; 375 } 376 377 current_time = qemu_clock_get_ns(timer_list->clock->type); 378 for(;;) { 379 ts = timer_list->active_timers; 380 if (!timer_expired_ns(ts, current_time)) { 381 break; 382 } 383 /* remove timer from the list before calling the callback */ 384 timer_list->active_timers = ts->next; 385 ts->next = NULL; 386 387 /* run the callback (the timer list can be modified) */ 388 ts->cb(ts->opaque); 389 progress = true; 390 } 391 return progress; 392 } 393 394 bool qemu_clock_run_timers(QEMUClockType type) 395 { 396 return timerlist_run_timers(main_loop_tlg.tl[type]); 397 } 398 399 void timerlistgroup_init(QEMUTimerListGroup *tlg, 400 QEMUTimerListNotifyCB *cb, void *opaque) 401 { 402 QEMUClockType type; 403 for (type = 0; type < QEMU_CLOCK_MAX; type++) { 404 tlg->tl[type] = timerlist_new(type, cb, opaque); 405 } 406 } 407 408 void timerlistgroup_deinit(QEMUTimerListGroup *tlg) 409 { 410 QEMUClockType type; 411 for (type = 0; type < QEMU_CLOCK_MAX; type++) { 412 timerlist_free(tlg->tl[type]); 413 } 414 } 415 416 bool timerlistgroup_run_timers(QEMUTimerListGroup *tlg) 417 { 418 QEMUClockType type; 419 bool progress = false; 420 for (type = 0; type < QEMU_CLOCK_MAX; type++) { 421 progress |= timerlist_run_timers(tlg->tl[type]); 422 } 423 return progress; 424 } 425 426 int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg) 427 { 428 int64_t deadline = -1; 429 QEMUClockType type; 430 for (type = 0; type < QEMU_CLOCK_MAX; type++) { 431 if (qemu_clock_use_for_deadline(tlg->tl[type]->clock->type)) { 432 deadline = qemu_soonest_timeout(deadline, 433 timerlist_deadline_ns( 434 tlg->tl[type])); 435 } 436 } 437 return deadline; 438 } 439 440 int64_t qemu_clock_get_ns(QEMUClockType type) 441 { 442 int64_t now, last; 443 QEMUClock *clock = qemu_clock_ptr(type); 444 445 switch (type) { 446 case QEMU_CLOCK_REALTIME: 447 return get_clock(); 448 default: 449 case QEMU_CLOCK_VIRTUAL: 450 if (use_icount) { 451 return cpu_get_icount(); 452 } else { 453 return cpu_get_clock(); 454 } 455 case QEMU_CLOCK_HOST: 456 now = get_clock_realtime(); 457 last = clock->last; 458 clock->last = now; 459 if (now < last) { 460 notifier_list_notify(&clock->reset_notifiers, &now); 461 } 462 return now; 463 } 464 } 465 466 void qemu_clock_register_reset_notifier(QEMUClockType type, 467 Notifier *notifier) 468 { 469 QEMUClock *clock = qemu_clock_ptr(type); 470 notifier_list_add(&clock->reset_notifiers, notifier); 471 } 472 473 void qemu_clock_unregister_reset_notifier(QEMUClockType type, 474 Notifier *notifier) 475 { 476 notifier_remove(notifier); 477 } 478 479 void init_clocks(void) 480 { 481 QEMUClockType type; 482 for (type = 0; type < QEMU_CLOCK_MAX; type++) { 483 qemu_clock_init(type); 484 } 485 486 #ifdef CONFIG_PRCTL_PR_SET_TIMERSLACK 487 prctl(PR_SET_TIMERSLACK, 1, 0, 0, 0); 488 #endif 489 } 490 491 uint64_t timer_expire_time_ns(QEMUTimer *ts) 492 { 493 return timer_pending(ts) ? ts->expire_time : -1; 494 } 495 496 bool qemu_clock_run_all_timers(void) 497 { 498 bool progress = false; 499 QEMUClockType type; 500 501 for (type = 0; type < QEMU_CLOCK_MAX; type++) { 502 progress |= qemu_clock_run_timers(type); 503 } 504 505 return progress; 506 } 507