/** * set next_timer to the next lowest enabled timer index */ void schedule_timer(void) { /* try to find *an active* timer */ next_timer = -1; for (int i = 0; i < HWTIMER_MAXTIMERS; i++) { if (native_hwtimer_isset[i] == 1) { next_timer = i; break; } } if (next_timer == -1) { DEBUG("schedule_timer(): no valid timer found - nothing to schedule\n"); struct itimerval null_timer; null_timer.it_interval.tv_sec = 0; null_timer.it_interval.tv_usec = 0; null_timer.it_value.tv_sec = 0; null_timer.it_value.tv_usec = 0; if (real_setitimer(ITIMER_REAL, &null_timer, NULL) == -1) { err(EXIT_FAILURE, "schedule_timer: setitimer"); } return; } /* find the next pending timer (next_timer now points to *a* valid pending timer) */ for (int i = 0; i < HWTIMER_MAXTIMERS; i++) { if ( (native_hwtimer_isset[i] == 1) && (tv2ticks(&(native_hwtimer[i].it_value)) < tv2ticks(&(native_hwtimer[next_timer].it_value))) ) { /* timer in slot i is active and the timeout is more recent than next_timer */ next_timer = i; } } /* next pending timer is in slot next_timer */ struct timeval now; hwtimer_arch_now(); // update timer ticks2tv(native_hwtimer_now, &now); struct itimerval result; memset(&result, 0, sizeof(result)); int retval = timeval_subtract(&result.it_value, &native_hwtimer[next_timer].it_value, &now); if (retval || (tv2ticks(&result.it_value) < HWTIMERMINOFFSET)) { DEBUG("\033[31mschedule_timer(): timer is already due (%i), mitigating.\033[0m\n", next_timer); result.it_value.tv_sec = 0; result.it_value.tv_usec = 1; } _native_syscall_enter(); if (real_setitimer(ITIMER_REAL, &result, NULL) == -1) { err(EXIT_FAILURE, "schedule_timer: setitimer"); } else { DEBUG("schedule_timer(): set next timer (%i).\n", next_timer); } _native_syscall_leave(); }
static void do_timer_set(unsigned int offset) { DEBUG("%s\n", __func__); if (offset && offset < NATIVE_TIMER_MIN_RES) { offset = NATIVE_TIMER_MIN_RES; } memset(&itv, 0, sizeof(itv)); itv.it_value.tv_sec = (offset / 1000000); itv.it_value.tv_usec = offset % 1000000; DEBUG("timer_set(): setting %u.%06u\n", (unsigned)itv.it_value.tv_sec, (unsigned)itv.it_value.tv_usec); _native_syscall_enter(); if (real_setitimer(ITIMER_REAL, &itv, NULL) == -1) { err(EXIT_FAILURE, "timer_arm: setitimer"); } _native_syscall_leave(); }