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.h" 26 #include "net.h" 27 #include "monitor.h" 28 #include "console.h" 29 30 #include "hw/hw.h" 31 32 #include <unistd.h> 33 #include <fcntl.h> 34 #include <time.h> 35 #include <errno.h> 36 #include <sys/time.h> 37 #include <signal.h> 38 #ifdef __FreeBSD__ 39 #include <sys/param.h> 40 #endif 41 42 #ifdef _WIN32 43 #include <windows.h> 44 #include <mmsystem.h> 45 #endif 46 47 #include "qemu-timer.h" 48 49 /***********************************************************/ 50 /* timers */ 51 52 #define QEMU_CLOCK_REALTIME 0 53 #define QEMU_CLOCK_VIRTUAL 1 54 #define QEMU_CLOCK_HOST 2 55 56 struct QEMUClock { 57 int type; 58 int enabled; 59 60 QEMUTimer *active_timers; 61 62 NotifierList reset_notifiers; 63 int64_t last; 64 }; 65 66 struct QEMUTimer { 67 QEMUClock *clock; 68 int64_t expire_time; /* in nanoseconds */ 69 int scale; 70 QEMUTimerCB *cb; 71 void *opaque; 72 struct QEMUTimer *next; 73 }; 74 75 struct qemu_alarm_timer { 76 char const *name; 77 int (*start)(struct qemu_alarm_timer *t); 78 void (*stop)(struct qemu_alarm_timer *t); 79 void (*rearm)(struct qemu_alarm_timer *t, int64_t nearest_delta_ns); 80 #if defined(__linux__) 81 int fd; 82 timer_t timer; 83 #elif defined(_WIN32) 84 HANDLE timer; 85 #endif 86 char expired; 87 char pending; 88 }; 89 90 static struct qemu_alarm_timer *alarm_timer; 91 92 static bool qemu_timer_expired_ns(QEMUTimer *timer_head, int64_t current_time) 93 { 94 return timer_head && (timer_head->expire_time <= current_time); 95 } 96 97 int qemu_alarm_pending(void) 98 { 99 return alarm_timer->pending; 100 } 101 102 static inline int alarm_has_dynticks(struct qemu_alarm_timer *t) 103 { 104 return !!t->rearm; 105 } 106 107 static int64_t qemu_next_alarm_deadline(void) 108 { 109 int64_t delta; 110 int64_t rtdelta; 111 112 if (!use_icount && vm_clock->active_timers) { 113 delta = vm_clock->active_timers->expire_time - 114 qemu_get_clock_ns(vm_clock); 115 } else { 116 delta = INT32_MAX; 117 } 118 if (host_clock->active_timers) { 119 int64_t hdelta = host_clock->active_timers->expire_time - 120 qemu_get_clock_ns(host_clock); 121 if (hdelta < delta) { 122 delta = hdelta; 123 } 124 } 125 if (rt_clock->active_timers) { 126 rtdelta = (rt_clock->active_timers->expire_time - 127 qemu_get_clock_ns(rt_clock)); 128 if (rtdelta < delta) { 129 delta = rtdelta; 130 } 131 } 132 133 return delta; 134 } 135 136 static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t) 137 { 138 int64_t nearest_delta_ns; 139 assert(alarm_has_dynticks(t)); 140 if (!rt_clock->active_timers && 141 !vm_clock->active_timers && 142 !host_clock->active_timers) { 143 return; 144 } 145 nearest_delta_ns = qemu_next_alarm_deadline(); 146 t->rearm(t, nearest_delta_ns); 147 } 148 149 /* TODO: MIN_TIMER_REARM_NS should be optimized */ 150 #define MIN_TIMER_REARM_NS 250000 151 152 #ifdef _WIN32 153 154 static int mm_start_timer(struct qemu_alarm_timer *t); 155 static void mm_stop_timer(struct qemu_alarm_timer *t); 156 static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta); 157 158 static int win32_start_timer(struct qemu_alarm_timer *t); 159 static void win32_stop_timer(struct qemu_alarm_timer *t); 160 static void win32_rearm_timer(struct qemu_alarm_timer *t, int64_t delta); 161 162 #else 163 164 static int unix_start_timer(struct qemu_alarm_timer *t); 165 static void unix_stop_timer(struct qemu_alarm_timer *t); 166 static void unix_rearm_timer(struct qemu_alarm_timer *t, int64_t delta); 167 168 #ifdef __linux__ 169 170 static int dynticks_start_timer(struct qemu_alarm_timer *t); 171 static void dynticks_stop_timer(struct qemu_alarm_timer *t); 172 static void dynticks_rearm_timer(struct qemu_alarm_timer *t, int64_t delta); 173 174 #endif /* __linux__ */ 175 176 #endif /* _WIN32 */ 177 178 static struct qemu_alarm_timer alarm_timers[] = { 179 #ifndef _WIN32 180 #ifdef __linux__ 181 {"dynticks", dynticks_start_timer, 182 dynticks_stop_timer, dynticks_rearm_timer}, 183 #endif 184 {"unix", unix_start_timer, unix_stop_timer, unix_rearm_timer}, 185 #else 186 {"mmtimer", mm_start_timer, mm_stop_timer, NULL}, 187 {"mmtimer2", mm_start_timer, mm_stop_timer, mm_rearm_timer}, 188 {"dynticks", win32_start_timer, win32_stop_timer, win32_rearm_timer}, 189 {"win32", win32_start_timer, win32_stop_timer, NULL}, 190 #endif 191 {NULL, } 192 }; 193 194 static void show_available_alarms(void) 195 { 196 int i; 197 198 printf("Available alarm timers, in order of precedence:\n"); 199 for (i = 0; alarm_timers[i].name; i++) 200 printf("%s\n", alarm_timers[i].name); 201 } 202 203 void configure_alarms(char const *opt) 204 { 205 int i; 206 int cur = 0; 207 int count = ARRAY_SIZE(alarm_timers) - 1; 208 char *arg; 209 char *name; 210 struct qemu_alarm_timer tmp; 211 212 if (!strcmp(opt, "?")) { 213 show_available_alarms(); 214 exit(0); 215 } 216 217 arg = g_strdup(opt); 218 219 /* Reorder the array */ 220 name = strtok(arg, ","); 221 while (name) { 222 for (i = 0; i < count && alarm_timers[i].name; i++) { 223 if (!strcmp(alarm_timers[i].name, name)) 224 break; 225 } 226 227 if (i == count) { 228 fprintf(stderr, "Unknown clock %s\n", name); 229 goto next; 230 } 231 232 if (i < cur) 233 /* Ignore */ 234 goto next; 235 236 /* Swap */ 237 tmp = alarm_timers[i]; 238 alarm_timers[i] = alarm_timers[cur]; 239 alarm_timers[cur] = tmp; 240 241 cur++; 242 next: 243 name = strtok(NULL, ","); 244 } 245 246 g_free(arg); 247 248 if (cur) { 249 /* Disable remaining timers */ 250 for (i = cur; i < count; i++) 251 alarm_timers[i].name = NULL; 252 } else { 253 show_available_alarms(); 254 exit(1); 255 } 256 } 257 258 QEMUClock *rt_clock; 259 QEMUClock *vm_clock; 260 QEMUClock *host_clock; 261 262 static QEMUClock *qemu_new_clock(int type) 263 { 264 QEMUClock *clock; 265 266 clock = g_malloc0(sizeof(QEMUClock)); 267 clock->type = type; 268 clock->enabled = 1; 269 notifier_list_init(&clock->reset_notifiers); 270 /* required to detect & report backward jumps */ 271 if (type == QEMU_CLOCK_HOST) { 272 clock->last = get_clock_realtime(); 273 } 274 return clock; 275 } 276 277 void qemu_clock_enable(QEMUClock *clock, int enabled) 278 { 279 clock->enabled = enabled; 280 } 281 282 int64_t qemu_clock_has_timers(QEMUClock *clock) 283 { 284 return !!clock->active_timers; 285 } 286 287 int64_t qemu_clock_expired(QEMUClock *clock) 288 { 289 return (clock->active_timers && 290 clock->active_timers->expire_time < qemu_get_clock_ns(clock)); 291 } 292 293 int64_t qemu_clock_deadline(QEMUClock *clock) 294 { 295 /* To avoid problems with overflow limit this to 2^32. */ 296 int64_t delta = INT32_MAX; 297 298 if (clock->active_timers) { 299 delta = clock->active_timers->expire_time - qemu_get_clock_ns(clock); 300 } 301 if (delta < 0) { 302 delta = 0; 303 } 304 return delta; 305 } 306 307 QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale, 308 QEMUTimerCB *cb, void *opaque) 309 { 310 QEMUTimer *ts; 311 312 ts = g_malloc0(sizeof(QEMUTimer)); 313 ts->clock = clock; 314 ts->cb = cb; 315 ts->opaque = opaque; 316 ts->scale = scale; 317 return ts; 318 } 319 320 void qemu_free_timer(QEMUTimer *ts) 321 { 322 g_free(ts); 323 } 324 325 /* stop a timer, but do not dealloc it */ 326 void qemu_del_timer(QEMUTimer *ts) 327 { 328 QEMUTimer **pt, *t; 329 330 /* NOTE: this code must be signal safe because 331 qemu_timer_expired() can be called from a signal. */ 332 pt = &ts->clock->active_timers; 333 for(;;) { 334 t = *pt; 335 if (!t) 336 break; 337 if (t == ts) { 338 *pt = t->next; 339 break; 340 } 341 pt = &t->next; 342 } 343 } 344 345 /* modify the current timer so that it will be fired when current_time 346 >= expire_time. The corresponding callback will be called. */ 347 static void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time) 348 { 349 QEMUTimer **pt, *t; 350 351 qemu_del_timer(ts); 352 353 /* add the timer in the sorted list */ 354 /* NOTE: this code must be signal safe because 355 qemu_timer_expired() can be called from a signal. */ 356 pt = &ts->clock->active_timers; 357 for(;;) { 358 t = *pt; 359 if (!qemu_timer_expired_ns(t, expire_time)) { 360 break; 361 } 362 pt = &t->next; 363 } 364 ts->expire_time = expire_time; 365 ts->next = *pt; 366 *pt = ts; 367 368 /* Rearm if necessary */ 369 if (pt == &ts->clock->active_timers) { 370 if (!alarm_timer->pending) { 371 qemu_rearm_alarm_timer(alarm_timer); 372 } 373 /* Interrupt execution to force deadline recalculation. */ 374 qemu_clock_warp(ts->clock); 375 if (use_icount) { 376 qemu_notify_event(); 377 } 378 } 379 } 380 381 /* modify the current timer so that it will be fired when current_time 382 >= expire_time. The corresponding callback will be called. */ 383 void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time) 384 { 385 qemu_mod_timer_ns(ts, expire_time * ts->scale); 386 } 387 388 int qemu_timer_pending(QEMUTimer *ts) 389 { 390 QEMUTimer *t; 391 for (t = ts->clock->active_timers; t != NULL; t = t->next) { 392 if (t == ts) 393 return 1; 394 } 395 return 0; 396 } 397 398 int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time) 399 { 400 return qemu_timer_expired_ns(timer_head, current_time * timer_head->scale); 401 } 402 403 static void qemu_run_timers(QEMUClock *clock) 404 { 405 QEMUTimer **ptimer_head, *ts; 406 int64_t current_time; 407 408 if (!clock->enabled) 409 return; 410 411 current_time = qemu_get_clock_ns(clock); 412 ptimer_head = &clock->active_timers; 413 for(;;) { 414 ts = *ptimer_head; 415 if (!qemu_timer_expired_ns(ts, current_time)) { 416 break; 417 } 418 /* remove timer from the list before calling the callback */ 419 *ptimer_head = ts->next; 420 ts->next = NULL; 421 422 /* run the callback (the timer list can be modified) */ 423 ts->cb(ts->opaque); 424 } 425 } 426 427 int64_t qemu_get_clock_ns(QEMUClock *clock) 428 { 429 int64_t now, last; 430 431 switch(clock->type) { 432 case QEMU_CLOCK_REALTIME: 433 return get_clock(); 434 default: 435 case QEMU_CLOCK_VIRTUAL: 436 if (use_icount) { 437 return cpu_get_icount(); 438 } else { 439 return cpu_get_clock(); 440 } 441 case QEMU_CLOCK_HOST: 442 now = get_clock_realtime(); 443 last = clock->last; 444 clock->last = now; 445 if (now < last) { 446 notifier_list_notify(&clock->reset_notifiers, &now); 447 } 448 return now; 449 } 450 } 451 452 void qemu_register_clock_reset_notifier(QEMUClock *clock, Notifier *notifier) 453 { 454 notifier_list_add(&clock->reset_notifiers, notifier); 455 } 456 457 void qemu_unregister_clock_reset_notifier(QEMUClock *clock, Notifier *notifier) 458 { 459 notifier_list_remove(&clock->reset_notifiers, notifier); 460 } 461 462 void init_clocks(void) 463 { 464 rt_clock = qemu_new_clock(QEMU_CLOCK_REALTIME); 465 vm_clock = qemu_new_clock(QEMU_CLOCK_VIRTUAL); 466 host_clock = qemu_new_clock(QEMU_CLOCK_HOST); 467 468 rtc_clock = host_clock; 469 } 470 471 /* save a timer */ 472 void qemu_put_timer(QEMUFile *f, QEMUTimer *ts) 473 { 474 uint64_t expire_time; 475 476 if (qemu_timer_pending(ts)) { 477 expire_time = ts->expire_time; 478 } else { 479 expire_time = -1; 480 } 481 qemu_put_be64(f, expire_time); 482 } 483 484 void qemu_get_timer(QEMUFile *f, QEMUTimer *ts) 485 { 486 uint64_t expire_time; 487 488 expire_time = qemu_get_be64(f); 489 if (expire_time != -1) { 490 qemu_mod_timer_ns(ts, expire_time); 491 } else { 492 qemu_del_timer(ts); 493 } 494 } 495 496 void qemu_run_all_timers(void) 497 { 498 alarm_timer->pending = 0; 499 500 /* rearm timer, if not periodic */ 501 if (alarm_timer->expired) { 502 alarm_timer->expired = 0; 503 qemu_rearm_alarm_timer(alarm_timer); 504 } 505 506 /* vm time timers */ 507 qemu_run_timers(vm_clock); 508 qemu_run_timers(rt_clock); 509 qemu_run_timers(host_clock); 510 } 511 512 #ifdef _WIN32 513 static void CALLBACK host_alarm_handler(PVOID lpParam, BOOLEAN unused) 514 #else 515 static void host_alarm_handler(int host_signum) 516 #endif 517 { 518 struct qemu_alarm_timer *t = alarm_timer; 519 if (!t) 520 return; 521 522 #if 0 523 #define DISP_FREQ 1000 524 { 525 static int64_t delta_min = INT64_MAX; 526 static int64_t delta_max, delta_cum, last_clock, delta, ti; 527 static int count; 528 ti = qemu_get_clock_ns(vm_clock); 529 if (last_clock != 0) { 530 delta = ti - last_clock; 531 if (delta < delta_min) 532 delta_min = delta; 533 if (delta > delta_max) 534 delta_max = delta; 535 delta_cum += delta; 536 if (++count == DISP_FREQ) { 537 printf("timer: min=%" PRId64 " us max=%" PRId64 " us avg=%" PRId64 " us avg_freq=%0.3f Hz\n", 538 muldiv64(delta_min, 1000000, get_ticks_per_sec()), 539 muldiv64(delta_max, 1000000, get_ticks_per_sec()), 540 muldiv64(delta_cum, 1000000 / DISP_FREQ, get_ticks_per_sec()), 541 (double)get_ticks_per_sec() / ((double)delta_cum / DISP_FREQ)); 542 count = 0; 543 delta_min = INT64_MAX; 544 delta_max = 0; 545 delta_cum = 0; 546 } 547 } 548 last_clock = ti; 549 } 550 #endif 551 if (alarm_has_dynticks(t) || 552 qemu_next_alarm_deadline () <= 0) { 553 t->expired = alarm_has_dynticks(t); 554 t->pending = 1; 555 qemu_notify_event(); 556 } 557 } 558 559 #if defined(__linux__) 560 561 #include "compatfd.h" 562 563 static int dynticks_start_timer(struct qemu_alarm_timer *t) 564 { 565 struct sigevent ev; 566 timer_t host_timer; 567 struct sigaction act; 568 569 sigfillset(&act.sa_mask); 570 act.sa_flags = 0; 571 act.sa_handler = host_alarm_handler; 572 573 sigaction(SIGALRM, &act, NULL); 574 575 /* 576 * Initialize ev struct to 0 to avoid valgrind complaining 577 * about uninitialized data in timer_create call 578 */ 579 memset(&ev, 0, sizeof(ev)); 580 ev.sigev_value.sival_int = 0; 581 ev.sigev_notify = SIGEV_SIGNAL; 582 #ifdef SIGEV_THREAD_ID 583 if (qemu_signalfd_available()) { 584 ev.sigev_notify = SIGEV_THREAD_ID; 585 ev._sigev_un._tid = qemu_get_thread_id(); 586 } 587 #endif /* SIGEV_THREAD_ID */ 588 ev.sigev_signo = SIGALRM; 589 590 if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) { 591 perror("timer_create"); 592 593 /* disable dynticks */ 594 fprintf(stderr, "Dynamic Ticks disabled\n"); 595 596 return -1; 597 } 598 599 t->timer = host_timer; 600 601 return 0; 602 } 603 604 static void dynticks_stop_timer(struct qemu_alarm_timer *t) 605 { 606 timer_t host_timer = t->timer; 607 608 timer_delete(host_timer); 609 } 610 611 static void dynticks_rearm_timer(struct qemu_alarm_timer *t, 612 int64_t nearest_delta_ns) 613 { 614 timer_t host_timer = t->timer; 615 struct itimerspec timeout; 616 int64_t current_ns; 617 618 if (nearest_delta_ns < MIN_TIMER_REARM_NS) 619 nearest_delta_ns = MIN_TIMER_REARM_NS; 620 621 /* check whether a timer is already running */ 622 if (timer_gettime(host_timer, &timeout)) { 623 perror("gettime"); 624 fprintf(stderr, "Internal timer error: aborting\n"); 625 exit(1); 626 } 627 current_ns = timeout.it_value.tv_sec * 1000000000LL + timeout.it_value.tv_nsec; 628 if (current_ns && current_ns <= nearest_delta_ns) 629 return; 630 631 timeout.it_interval.tv_sec = 0; 632 timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */ 633 timeout.it_value.tv_sec = nearest_delta_ns / 1000000000; 634 timeout.it_value.tv_nsec = nearest_delta_ns % 1000000000; 635 if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) { 636 perror("settime"); 637 fprintf(stderr, "Internal timer error: aborting\n"); 638 exit(1); 639 } 640 } 641 642 #endif /* defined(__linux__) */ 643 644 #if !defined(_WIN32) 645 646 static int unix_start_timer(struct qemu_alarm_timer *t) 647 { 648 struct sigaction act; 649 650 /* timer signal */ 651 sigfillset(&act.sa_mask); 652 act.sa_flags = 0; 653 act.sa_handler = host_alarm_handler; 654 655 sigaction(SIGALRM, &act, NULL); 656 return 0; 657 } 658 659 static void unix_rearm_timer(struct qemu_alarm_timer *t, 660 int64_t nearest_delta_ns) 661 { 662 struct itimerval itv; 663 int err; 664 665 if (nearest_delta_ns < MIN_TIMER_REARM_NS) 666 nearest_delta_ns = MIN_TIMER_REARM_NS; 667 668 itv.it_interval.tv_sec = 0; 669 itv.it_interval.tv_usec = 0; /* 0 for one-shot timer */ 670 itv.it_value.tv_sec = nearest_delta_ns / 1000000000; 671 itv.it_value.tv_usec = (nearest_delta_ns % 1000000000) / 1000; 672 err = setitimer(ITIMER_REAL, &itv, NULL); 673 if (err) { 674 perror("setitimer"); 675 fprintf(stderr, "Internal timer error: aborting\n"); 676 exit(1); 677 } 678 } 679 680 static void unix_stop_timer(struct qemu_alarm_timer *t) 681 { 682 struct itimerval itv; 683 684 memset(&itv, 0, sizeof(itv)); 685 setitimer(ITIMER_REAL, &itv, NULL); 686 } 687 688 #endif /* !defined(_WIN32) */ 689 690 691 #ifdef _WIN32 692 693 static MMRESULT mm_timer; 694 static unsigned mm_period; 695 696 static void CALLBACK mm_alarm_handler(UINT uTimerID, UINT uMsg, 697 DWORD_PTR dwUser, DWORD_PTR dw1, 698 DWORD_PTR dw2) 699 { 700 struct qemu_alarm_timer *t = alarm_timer; 701 if (!t) { 702 return; 703 } 704 if (alarm_has_dynticks(t) || qemu_next_alarm_deadline() <= 0) { 705 t->expired = alarm_has_dynticks(t); 706 t->pending = 1; 707 qemu_notify_event(); 708 } 709 } 710 711 static int mm_start_timer(struct qemu_alarm_timer *t) 712 { 713 TIMECAPS tc; 714 UINT flags; 715 716 memset(&tc, 0, sizeof(tc)); 717 timeGetDevCaps(&tc, sizeof(tc)); 718 719 mm_period = tc.wPeriodMin; 720 timeBeginPeriod(mm_period); 721 722 flags = TIME_CALLBACK_FUNCTION; 723 if (alarm_has_dynticks(t)) { 724 flags |= TIME_ONESHOT; 725 } else { 726 flags |= TIME_PERIODIC; 727 } 728 729 mm_timer = timeSetEvent(1, /* interval (ms) */ 730 mm_period, /* resolution */ 731 mm_alarm_handler, /* function */ 732 (DWORD_PTR)t, /* parameter */ 733 flags); 734 735 if (!mm_timer) { 736 fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n", 737 GetLastError()); 738 timeEndPeriod(mm_period); 739 return -1; 740 } 741 742 return 0; 743 } 744 745 static void mm_stop_timer(struct qemu_alarm_timer *t) 746 { 747 timeKillEvent(mm_timer); 748 timeEndPeriod(mm_period); 749 } 750 751 static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta) 752 { 753 int nearest_delta_ms = (delta + 999999) / 1000000; 754 if (nearest_delta_ms < 1) { 755 nearest_delta_ms = 1; 756 } 757 758 timeKillEvent(mm_timer); 759 mm_timer = timeSetEvent(nearest_delta_ms, 760 mm_period, 761 mm_alarm_handler, 762 (DWORD_PTR)t, 763 TIME_ONESHOT | TIME_CALLBACK_FUNCTION); 764 765 if (!mm_timer) { 766 fprintf(stderr, "Failed to re-arm win32 alarm timer %ld\n", 767 GetLastError()); 768 769 timeEndPeriod(mm_period); 770 exit(1); 771 } 772 } 773 774 static int win32_start_timer(struct qemu_alarm_timer *t) 775 { 776 HANDLE hTimer; 777 BOOLEAN success; 778 779 /* If you call ChangeTimerQueueTimer on a one-shot timer (its period 780 is zero) that has already expired, the timer is not updated. Since 781 creating a new timer is relatively expensive, set a bogus one-hour 782 interval in the dynticks case. */ 783 success = CreateTimerQueueTimer(&hTimer, 784 NULL, 785 host_alarm_handler, 786 t, 787 1, 788 alarm_has_dynticks(t) ? 3600000 : 1, 789 WT_EXECUTEINTIMERTHREAD); 790 791 if (!success) { 792 fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n", 793 GetLastError()); 794 return -1; 795 } 796 797 t->timer = hTimer; 798 return 0; 799 } 800 801 static void win32_stop_timer(struct qemu_alarm_timer *t) 802 { 803 HANDLE hTimer = t->timer; 804 805 if (hTimer) { 806 DeleteTimerQueueTimer(NULL, hTimer, NULL); 807 } 808 } 809 810 static void win32_rearm_timer(struct qemu_alarm_timer *t, 811 int64_t nearest_delta_ns) 812 { 813 HANDLE hTimer = t->timer; 814 int nearest_delta_ms; 815 BOOLEAN success; 816 817 nearest_delta_ms = (nearest_delta_ns + 999999) / 1000000; 818 if (nearest_delta_ms < 1) { 819 nearest_delta_ms = 1; 820 } 821 success = ChangeTimerQueueTimer(NULL, 822 hTimer, 823 nearest_delta_ms, 824 3600000); 825 826 if (!success) { 827 fprintf(stderr, "Failed to rearm win32 alarm timer: %ld\n", 828 GetLastError()); 829 exit(-1); 830 } 831 832 } 833 834 #endif /* _WIN32 */ 835 836 static void alarm_timer_on_change_state_rearm(void *opaque, int running, 837 RunState state) 838 { 839 if (running) 840 qemu_rearm_alarm_timer((struct qemu_alarm_timer *) opaque); 841 } 842 843 int init_timer_alarm(void) 844 { 845 struct qemu_alarm_timer *t = NULL; 846 int i, err = -1; 847 848 for (i = 0; alarm_timers[i].name; i++) { 849 t = &alarm_timers[i]; 850 851 err = t->start(t); 852 if (!err) 853 break; 854 } 855 856 if (err) { 857 err = -ENOENT; 858 goto fail; 859 } 860 861 /* first event is at time 0 */ 862 t->pending = 1; 863 alarm_timer = t; 864 qemu_add_vm_change_state_handler(alarm_timer_on_change_state_rearm, t); 865 866 return 0; 867 868 fail: 869 return err; 870 } 871 872 void quit_timers(void) 873 { 874 struct qemu_alarm_timer *t = alarm_timer; 875 alarm_timer = NULL; 876 t->stop(t); 877 } 878 879 int qemu_calculate_timeout(void) 880 { 881 return 1000; 882 } 883 884