From 0f87493487d81522df481bcce7fc8eb5f3134d8d Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Fri, 14 Oct 2016 00:39:46 -0400 Subject: [PATCH] timer: Rework AVR timer priority code to use time instead of event count Rework the timer prioritization code so that is compares against the current time instead of the number of repeat timers in a given interrupt. This makes the code slightly faster and it should provide better protection against task starvation. Signed-off-by: Kevin O'Connor --- src/avr/timer.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/avr/timer.c b/src/avr/timer.c index e4d7b942..a7e832bc 100644 --- a/src/avr/timer.c +++ b/src/avr/timer.c @@ -42,6 +42,14 @@ timer_set_clear(uint16_t next) TIFR1 = 1<= 0) { // Next timer is in the near future - wait for time to occur now = timer_get(); @@ -161,13 +169,13 @@ timer_try_set_next(uint32_t target) } return 0; } - - // Too many repeat timers from a single interrupt - force a pause - timer_repeat = TIMER_MAX_NEXT_REPEAT; - next = now + TIMER_DEFER_REPEAT_TICKS; if (diff < (int16_t)(-timer_from_us(1000))) goto fail; + // Too many repeat timers - force a pause so tasks aren't starved + timer_repeat_set(now + TIMER_REPEAT_TICKS); + next = now + TIMER_DEFER_REPEAT_TICKS; + done: timer_set(next); return 1; @@ -175,9 +183,13 @@ fail: shutdown("Rescheduled timer in the past"); } +// Periodic background task that temporarily boosts priority of +// timers. This helps prioritize timers when tasks are idling. static void timer_task(void) { - timer_repeat = TIMER_MAX_REPEAT; + irq_disable(); + timer_repeat_set(timer_get() + TIMER_IDLE_REPEAT_TICKS); + irq_enable(); } DECL_TASK(timer_task);