aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2017-03-21 01:21:23 -0400
committerKevin O'Connor <kevin@koconnor.net>2017-03-26 22:45:58 -0400
commit59b71d5d05ca70ff8cc81296a25e14499987129c (patch)
tree084e5b8d32ed3bd8bd3ff7431ee14e52eed7703d
parent4dfa6c6ee454d14a006033e218acbb7fa9ced8bd (diff)
downloadkutter-59b71d5d05ca70ff8cc81296a25e14499987129c.tar.gz
kutter-59b71d5d05ca70ff8cc81296a25e14499987129c.tar.xz
kutter-59b71d5d05ca70ff8cc81296a25e14499987129c.zip
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>
-rw-r--r--src/avr/Makefile2
-rw-r--r--src/avr/timer.c2
-rw-r--r--src/generic/misc.h2
-rw-r--r--src/generic/timer.c2
-rw-r--r--src/sched.c42
-rw-r--r--src/simulator/main.c2
6 files changed, 26 insertions, 26 deletions
diff --git a/src/avr/Makefile b/src/avr/Makefile
index af8d9f49..58d5c846 100644
--- a/src/avr/Makefile
+++ b/src/avr/Makefile
@@ -5,7 +5,7 @@ CROSS_PREFIX=avr-
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
# Add avr source files
diff --git a/src/avr/timer.c b/src/avr/timer.c
index f1fbd284..2de97526 100644
--- a/src/avr/timer.c
+++ b/src/avr/timer.c
@@ -153,7 +153,7 @@ timer_periodic(void)
// if the next timer is too close to schedule. Caller must disable
// irqs.
uint8_t
-timer_try_set_next(uint32_t target)
+timer_try_set_next(unsigned int target)
{
uint16_t next = target;
int16_t diff = next - timer_get();
diff --git a/src/generic/misc.h b/src/generic/misc.h
index b6d49ffd..bc3223e7 100644
--- a/src/generic/misc.h
+++ b/src/generic/misc.h
@@ -13,7 +13,7 @@ uint32_t timer_from_us(uint32_t us);
uint8_t timer_is_before(uint32_t time1, uint32_t time2);
uint32_t timer_read_time(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);
diff --git a/src/generic/timer.c b/src/generic/timer.c
index 436ecb68..256ccb3d 100644
--- a/src/generic/timer.c
+++ b/src/generic/timer.c
@@ -50,7 +50,7 @@ static uint32_t timer_repeat_until;
// if the next timer is too close to schedule. Caller must disable
// irqs.
uint8_t
-timer_try_set_next(uint32_t next)
+timer_try_set_next(unsigned int next)
{
uint32_t now = timer_read_time();
int32_t diff = next - now;
diff --git a/src/sched.c b/src/sched.c
index cae2f819..1e81f57b 100644
--- a/src/sched.c
+++ b/src/sched.c
@@ -122,55 +122,55 @@ sched_del_timer(struct timer *del)
irq_restore(flag);
}
-// Move a rescheduled timer to its new location in the list. Returns
-// the next timer to run.
-static struct timer *
-reschedule_timer(struct timer *t)
+// Move a rescheduled timer to its new location in the list.
+static void
+reschedule_timer(struct timer *t, uint32_t updated_waketime)
{
- 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
+ struct timer *pos = t->next, *prev;
timer_list = pos;
- struct timer *prev;
for (;;) {
prev = pos;
if (CONFIG_MACH_AVR)
// micro optimization for AVR - reduces register pressure
- asm("" : "+r"(prev) : : "memory");
+ asm("" : "+r"(prev));
pos = pos->next;
- if (timer_is_before(waketime, pos->waketime))
+ if (timer_is_before(updated_waketime, pos->waketime))
break;
}
t->next = pos;
prev->next = t;
- return timer_list;
}
// Invoke timers - called from board timer irq code.
void
sched_timer_kick(void)
{
- struct timer *t = timer_list;
for (;;) {
// Invoke timer callback
+ struct timer *t = timer_list;
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);
- else
+ updated_waketime = t->waketime;
+ } else {
res = t->func(t);
+ updated_waketime = t->waketime;
+ }
// 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;
- else
- t = reschedule_timer(t);
+ next_waketime = t->waketime;
+ } 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)
- res = timer_try_set_next(t->waketime);
+ res = timer_try_set_next(next_waketime);
if (res)
break;
}
diff --git a/src/simulator/main.c b/src/simulator/main.c
index 4f715ab2..eb3025ca 100644
--- a/src/simulator/main.c
+++ b/src/simulator/main.c
@@ -76,7 +76,7 @@ timer_read_time(void)
}
uint8_t
-timer_try_set_next(uint32_t next)
+timer_try_set_next(unsigned int next)
{
return 1;
}