sched: Be explicit with loading of the waketime variable

Explicilty load the timer waketime variable into local variables in
sched_timer_kick().  Change the optimization level from Os to O2.
This helps gcc to avoid unnecessary reloads from memory in the common
stepper_event() case.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2017-03-21 01:21:23 -04:00
parent 4dfa6c6ee4
commit 59b71d5d05
6 changed files with 26 additions and 26 deletions

View File

@ -5,7 +5,7 @@ CROSS_PREFIX=avr-
dirs-y += src/avr lib/pjrc_usb_serial dirs-y += src/avr lib/pjrc_usb_serial
CFLAGS-y += -Os -mmcu=$(CONFIG_MCU) -DF_CPU=$(CONFIG_CLOCK_FREQ) CFLAGS-y += -O2 -mmcu=$(CONFIG_MCU) -DF_CPU=$(CONFIG_CLOCK_FREQ)
LDFLAGS-y += -Wl,--relax LDFLAGS-y += -Wl,--relax
# Add avr source files # Add avr source files

View File

@ -153,7 +153,7 @@ timer_periodic(void)
// if the next timer is too close to schedule. Caller must disable // if the next timer is too close to schedule. Caller must disable
// irqs. // irqs.
uint8_t uint8_t
timer_try_set_next(uint32_t target) timer_try_set_next(unsigned int target)
{ {
uint16_t next = target; uint16_t next = target;
int16_t diff = next - timer_get(); int16_t diff = next - timer_get();

View File

@ -13,7 +13,7 @@ uint32_t timer_from_us(uint32_t us);
uint8_t timer_is_before(uint32_t time1, uint32_t time2); uint8_t timer_is_before(uint32_t time1, uint32_t time2);
uint32_t timer_read_time(void); uint32_t timer_read_time(void);
void timer_periodic(void); void timer_periodic(void);
uint8_t timer_try_set_next(uint32_t next); uint8_t timer_try_set_next(unsigned int next);
size_t alloc_maxsize(size_t reqsize); size_t alloc_maxsize(size_t reqsize);

View File

@ -50,7 +50,7 @@ static uint32_t timer_repeat_until;
// if the next timer is too close to schedule. Caller must disable // if the next timer is too close to schedule. Caller must disable
// irqs. // irqs.
uint8_t uint8_t
timer_try_set_next(uint32_t next) timer_try_set_next(unsigned int next)
{ {
uint32_t now = timer_read_time(); uint32_t now = timer_read_time();
int32_t diff = next - now; int32_t diff = next - now;

View File

@ -122,55 +122,55 @@ sched_del_timer(struct timer *del)
irq_restore(flag); irq_restore(flag);
} }
// Move a rescheduled timer to its new location in the list. Returns // Move a rescheduled timer to its new location in the list.
// the next timer to run. static void
static struct timer * reschedule_timer(struct timer *t, uint32_t updated_waketime)
reschedule_timer(struct timer *t)
{ {
uint32_t waketime = t->waketime;
struct timer *pos = t->next;
if (timer_is_before(waketime, pos->waketime))
// Timer is still the first - no insertion needed
return t;
// Find new timer position and update list // Find new timer position and update list
struct timer *pos = t->next, *prev;
timer_list = pos; timer_list = pos;
struct timer *prev;
for (;;) { for (;;) {
prev = pos; prev = pos;
if (CONFIG_MACH_AVR) if (CONFIG_MACH_AVR)
// micro optimization for AVR - reduces register pressure // micro optimization for AVR - reduces register pressure
asm("" : "+r"(prev) : : "memory"); asm("" : "+r"(prev));
pos = pos->next; pos = pos->next;
if (timer_is_before(waketime, pos->waketime)) if (timer_is_before(updated_waketime, pos->waketime))
break; break;
} }
t->next = pos; t->next = pos;
prev->next = t; prev->next = t;
return timer_list;
} }
// Invoke timers - called from board timer irq code. // Invoke timers - called from board timer irq code.
void void
sched_timer_kick(void) sched_timer_kick(void)
{ {
struct timer *t = timer_list;
for (;;) { for (;;) {
// Invoke timer callback // Invoke timer callback
struct timer *t = timer_list;
uint_fast8_t res; uint_fast8_t res;
if (CONFIG_INLINE_STEPPER_HACK && likely(!t->func)) uint32_t updated_waketime;
if (CONFIG_INLINE_STEPPER_HACK && likely(!t->func)) {
res = stepper_event(t); res = stepper_event(t);
else updated_waketime = t->waketime;
} else {
res = t->func(t); res = t->func(t);
updated_waketime = t->waketime;
}
// Update timer_list (rescheduling current timer if necessary) // Update timer_list (rescheduling current timer if necessary)
if (unlikely(res == SF_DONE)) unsigned int next_waketime = updated_waketime;
if (unlikely(res == SF_DONE)) {
t = timer_list = t->next; t = timer_list = t->next;
else next_waketime = t->waketime;
t = reschedule_timer(t); } else if (!timer_is_before(updated_waketime, t->next->waketime)) {
next_waketime = t->next->waketime;
reschedule_timer(t, updated_waketime);
}
// Schedule next timer event (or run next timer if it's ready) // Schedule next timer event (or run next timer if it's ready)
res = timer_try_set_next(t->waketime); res = timer_try_set_next(next_waketime);
if (res) if (res)
break; break;
} }

View File

@ -76,7 +76,7 @@ timer_read_time(void)
} }
uint8_t uint8_t
timer_try_set_next(uint32_t next) timer_try_set_next(unsigned int next)
{ {
return 1; return 1;
} }