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