/*---------------------------------------------------------------------------*/ void rtimer_run_next(void) { struct rtimer *t; if(next_rtimer == NULL) { return; } t = next_rtimer; next_rtimer = NULL; #if GLOSSY if (t->overflows_to_go == 0) { // no more overflows to wait for t->func(t, t->ptr); } else { // we still have to wait for more timer overflows t->overflows_to_go--; next_rtimer = t; // rtimer_arch_schedule(next_rtimer->time); } #else t->func(t, t->ptr); #endif /* GLOSSY */ if(next_rtimer != NULL) { rtimer_arch_schedule(next_rtimer->time); } return; }
/*---------------------------------------------------------------------------*/ int rtimer_set(struct rtimer *rtimer, rtimer_clock_t time, rtimer_clock_t duration, rtimer_callback_t func, void *ptr) { int first = 0; PRINTF("rtimer_set time %d\n", time); if(next_rtimer == NULL) { first = 1; } rtimer->func = func; rtimer->ptr = ptr; #if GLOSSY rtimer->overflows_to_go = 0; #endif /* GLOSSY */ rtimer->time = time; next_rtimer = rtimer; if(first == 1) { rtimer_arch_schedule(time); } return RTIMER_OK; }
/*---------------------------------------------------------------------------*/ int rtimer_set_long(struct rtimer *rtimer, rtimer_clock_t ref_time, unsigned long offset, rtimer_callback_t func, void *ptr) { if(next_rtimer == NULL) { rtimer->func = func; rtimer->ptr = ptr; rtimer->time = ref_time + offset; next_rtimer = rtimer; // it is assumed here that the timer is scheduled within 2 seconds after ref_time if (offset < (unsigned long)RTIMER_SECOND * 2) { rtimer->overflows_to_go = 0; } else { rtimer_clock_t now = RTIMER_NOW(); rtimer->overflows_to_go = (offset - (now - ref_time)) >> 16; // It should never happen, but to be sure... if (rtimer->overflows_to_go == 0xffff) { rtimer->overflows_to_go = 0; } } rtimer_arch_schedule(ref_time + (rtimer_clock_t)offset); // printf("now %u, ref_time %u, offset %lu, TACCR0 %u\n", // now, ref_time, offset, TACCR0); }
static int set_locked(struct rtimer *rtimer, rtimer_clock_t time, rtimer_callback_t func, void *ptr) { struct rtimer **anchor; /* * RTIMER_ERR_ALREADY_SCHEDULED in rtimer.h suggests we should fail if the * timer is already scheduled. However, the original implementation allows * timers to be rescheduled with impunity, so we maintain de facto * compatibility. */ for (anchor = &next_rtimer; *anchor; anchor = &(*anchor)->next) if (*anchor == rtimer) { *anchor = rtimer->next; break; } rtimer->time = time; rtimer->func = func; rtimer->ptr = func; rtimer->cancel = 0; for (anchor = &next_rtimer; *anchor && RTIMER_CLOCK_LT((*anchor)->time, time); anchor = &(*anchor)->next); rtimer->next = *anchor; *anchor = rtimer; if (next_rtimer == rtimer) rtimer_arch_schedule(time); return RTIMER_OK; }
/*---------------------------------------------------------------------------*/ int rtimer_set(struct rtimer *rtimer, rtimer_clock_t time, rtimer_clock_t duration, rtimer_callback_t func, void *ptr) { int i; PRINTF("rtimer_set time %d\n", time); rtimer->func = func; rtimer->ptr = ptr; /* Check if rtimer queue is full. */ if(firstempty == (next - 1) % LIST_SIZE) { PRINTF("rtimer_set: next %d firstempty %d full\n", next, firstempty); return RTIMER_ERR_FULL; } /* Check if it is possible to run this rtimer at the requested time. */ for(i = next; i != firstempty; i = (i + 1) % LIST_SIZE) { if(rtimers[i] == rtimer) { /* Check if timer is already scheduled. If so, we do not schedule it again. */ return RTIMER_ERR_ALREADY_SCHEDULED; } /* XXX: should check a range of time not just the same precise moment. */ if(rtimers[i]->time == time) { PRINTF("rtimer_set: next %d firstempty %d time %d == %d\n", next, firstempty, rtimers[i]->time, time); return RTIMER_ERR_TIME; } } /* Put the rtimer at the end of the rtimer list. */ rtimer->time = time; rtimers[firstempty] = rtimer; PRINTF("rtimer_post: putting rtimer %p as %d\n", rtimer, firstempty); firstempty = (firstempty + 1) % LIST_SIZE; /* PRINTF("rtimer_post: next %d firstempty %d scheduling soon\n", next, firstempty);*/ /* Check if this is the first rtimer on the list. If so, we need to run the rtimer_arch_schedule() function to get the ball rolling. */ if(firstempty == (next + 1) % LIST_SIZE) { PRINTF("rtimer_set scheduling %d %p (%d)\n", next, rtimers[next], rtimers[next]->time); rtimer_arch_schedule(rtimers[next]->time); } return RTIMER_OK; }
static void next_timer_locked(void) { rtimer_clock_t now = RTIMER_NOW(); struct rtimer *t; while (next_rtimer && !RTIMER_CLOCK_LT(now, next_rtimer->time)) { t = next_rtimer; next_rtimer = t->next; if (!t->cancel) t->func(t, t->ptr); } if (next_rtimer) rtimer_arch_schedule(next_rtimer->time); }
/*---------------------------------------------------------------------------*/ void rtimer_run_next(void) { int i, n; struct rtimer *t; /* Do not run timer if list is empty. */ if(next == firstempty) { return; } t = rtimers[next]; /* Increase the pointer to the next rtimer. */ next = (next + 1) % LIST_SIZE; /* Run the rtimer. */ PRINTF("rtimer_run_next running %p\n", t); t->func(t, t->ptr); if(next == firstempty) { PRINTF("rtimer_run_next: empty rtimer list\n"); /* The list is empty, no more rtimers to schedule. */ return; } /* Find the next rtimer to run. */ n = next; for(i = next; i != firstempty; i = (i + 1) % LIST_SIZE) { PRINTF("rtimer_run_next checking %p (%d) against %p (%d)\n", rtimers[i], rtimers[i]->time, rtimers[n], rtimers[n]->time); if(RTIMER_CLOCK_LT(rtimers[i]->time, rtimers[n]->time)) { n = i; } } PRINTF("rtimer_run_next next rtimer is %d %p (%d)\n", n, rtimers[n], rtimers[n]->time); /* Put the next rtimer first in the rtimer list. */ t = rtimers[next]; rtimers[next] = rtimers[n]; rtimers[n] = t; PRINTF("rtimer_run_next scheduling %d %p (%d)\n", next, rtimers[next], rtimers[next]->time); rtimer_arch_schedule(rtimers[next]->time); }
/*---------------------------------------------------------------------------*/ void rtimer_run_next(void) { struct rtimer *t; if(next_rtimer == NULL) { return; } t = next_rtimer; next_rtimer = NULL; t->func(t, t->ptr); if(next_rtimer != NULL) { rtimer_arch_schedule(next_rtimer->time); } return; }
int rtimer_set_long(struct rtimer *rtimer, rtimer_clock_t ref_time, unsigned long offset, rtimer_clock_t duration, rtimer_callback_t func, void *ptr) { if(next_rtimer == NULL) { rtimer->func = func; rtimer->ptr = ptr; rtimer->time = ref_time + offset; next_rtimer = rtimer; // It is assumed here that the timer is scheduled within 2 seconds after t_ref rtimer_clock_t now = RTIMER_NOW(); rtimer->overflows_to_go = (offset - (now - ref_time)) >> 16; rtimer_arch_schedule(ref_time + (rtimer_clock_t)offset); // printf("now %u, ref_time %u, offset %lu, TACCR0 %u\n", // now, ref_time, offset, TACCR0); }
/*---------------------------------------------------------------------------*/ int rtimer_set(struct rtimer *rtimer, rtimer_clock_t time, rtimer_clock_t duration, rtimer_callback_t func, void *ptr) { PRINTF("rtimer_set time %d\n", time); if(next_rtimer) { return RTIMER_ERR_ALREADY_SCHEDULED; } rtimer->func = func; rtimer->ptr = ptr; rtimer->time = time; next_rtimer = rtimer; rtimer_arch_schedule(time); return RTIMER_OK; }
/*---------------------------------------------------------------------------*/ int rtimer_reset(struct rtimer *rtimer, rtimer_clock_t time, rtimer_clock_t duration, rtimer_callback_t func, void *ptr) { PRINTF("rtimer_reset time %d\n", time); next_rtimer = NULL; rtimer_arch_schedule(time); rtimer->func = func; rtimer->ptr = ptr; rtimer->time = time; next_rtimer = rtimer; return RTIMER_OK; }