// these timers are one shots, then get cleared if the timer function returns zero,
// they get reset if the callback function returns a new cycle number
uint32_t cycle_timer_map;
+ avr_cycle_count_t next_cycle_timer;
struct {
avr_cycle_count_t when;
avr_cycle_timer_t timer;
return;
}
when += avr->cycle;
+ if (when < avr->next_cycle_timer)
+ avr->next_cycle_timer = when;
for (int i = 0; i < 32; i++)
if (!(avr->cycle_timer_map & (1 << i))) {
avr->cycle_timer[i].timer = timer;
avr->cycle_timer[i].param = NULL;
avr->cycle_timer[i].when = 0;
avr->cycle_timer_map &= ~(1 << i);
+ // no need to reset next_cycle_timer; having too small
+ // a value there only causes some harmless extra
+ // computation.
return;
}
}
*/
avr_cycle_count_t avr_cycle_timer_process(avr_t * avr)
{
- if (!avr->cycle_timer_map)
+ // If we have previously determined that we don't need to fire
+ // cycle timers yet, we can do an early exit
+ if (avr->next_cycle_timer > avr->cycle)
+ return avr->next_cycle_timer - avr->cycle;
+
+ if (!avr->cycle_timer_map) {
+ avr->next_cycle_timer = (avr_cycle_count_t)-1;
return (avr_cycle_count_t)-1;
+ }
avr_cycle_count_t min = (avr_cycle_count_t)-1;
uint32_t map = avr->cycle_timer_map;
min = avr->cycle_timer[bit].when;
map &= ~(1 << bit);
}
+ avr->next_cycle_timer = min;
return min - avr->cycle;
}