| 519 | |
| 520 | |
| 521 | static void run_timer_process( void ) |
| 522 | { |
| 523 | unsigned int multiple; |
| 524 | unsigned int cnt; |
| 525 | struct timeval o_tv; |
| 526 | struct timeval tv, comp_tv; |
| 527 | utime_t drift; |
| 528 | utime_t uinterval; |
| 529 | utime_t wait; |
| 530 | utime_t ij; |
| 531 | |
| 532 | /* timer re-calibration to compensate drifting */ |
| 533 | #define compute_wait_with_drift(_tv) \ |
| 534 | do { \ |
| 535 | if ( drift > ITIMER_TICK ) { \ |
| 536 | wait = (drift >= uinterval) ? 0 : uinterval-drift; \ |
| 537 | _tv.tv_sec = wait / 1000000; \ |
| 538 | _tv.tv_usec = wait % 1000000; \ |
| 539 | drift -= uinterval-wait; \ |
| 540 | } else { \ |
| 541 | _tv = o_tv; \ |
| 542 | } \ |
| 543 | }while(0) |
| 544 | |
| 545 | |
| 546 | if ( (utimer_list==NULL) || ((TIMER_TICK*1000000) == UTIMER_TICK) ) { |
| 547 | o_tv.tv_sec = TIMER_TICK; |
| 548 | o_tv.tv_usec = 0; |
| 549 | multiple = 1; |
| 550 | } else { |
| 551 | o_tv.tv_sec = UTIMER_TICK / 1000000; |
| 552 | o_tv.tv_usec = UTIMER_TICK % 1000000; |
| 553 | multiple = (( TIMER_TICK * 1000000 ) / UTIMER_TICK ) / 1000000; |
| 554 | } |
| 555 | |
| 556 | LM_DBG(" tv = %ld, %ld, m=%d\n", |
| 557 | (long)o_tv.tv_sec,(long)o_tv.tv_usec,multiple); |
| 558 | |
| 559 | drift = 0; |
| 560 | uinterval = o_tv.tv_sec * 1000000 + o_tv.tv_usec; |
| 561 | |
| 562 | if (utimer_list==NULL) { |
| 563 | /* only TIMERs, ticking at TIMER_TICK */ |
| 564 | for( ; ; ) { |
| 565 | ij = *ijiffies; |
| 566 | compute_wait_with_drift(comp_tv); |
| 567 | tv = comp_tv; |
| 568 | select( 0, 0, 0, 0, &tv); |
| 569 | |
| 570 | timer_ticker( timer_list); |
| 571 | lock_get(tr_list_lock); |
| 572 | timer_ticker( *tr_timer_list); |
| 573 | lock_release(tr_list_lock); |
| 574 | |
| 575 | drift += ((utime_t)comp_tv.tv_sec*1000000+comp_tv.tv_usec > (*ijiffies-ij)) ? |
| 576 | 0 : *ijiffies-ij - ((utime_t)comp_tv.tv_sec*1000000+comp_tv.tv_usec); |
| 577 | } |
| 578 |
no test coverage detected