aboutsummaryrefslogtreecommitdiffstats
path: root/src/linux/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/linux/timer.c')
-rw-r--r--src/linux/timer.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/src/linux/timer.c b/src/linux/timer.c
index 30e45793..dd63f66f 100644
--- a/src/linux/timer.c
+++ b/src/linux/timer.c
@@ -100,11 +100,15 @@ timer_is_before(uint32_t time1, uint32_t time2)
return (int32_t)(time1 - time2) < 0;
}
+static uint32_t last_timer_read_time;
+
// Return the current time (in clock ticks)
uint32_t
timer_read_time(void)
{
- return timespec_to_time(timespec_read());
+ uint32_t t = timespec_to_time(timespec_read());
+ last_timer_read_time = t;
+ return t;
}
// Activate timer dispatch as soon as possible
@@ -126,11 +130,19 @@ static uint32_t timer_repeat_until;
static uint32_t
timer_dispatch_many(void)
{
- uint32_t tru = timer_repeat_until;
+ uint32_t tru = timer_repeat_until, prev_ltrt = 0;
for (;;) {
// Run the next software timer
uint32_t next = sched_timer_dispatch();
+ uint32_t ltrt = last_timer_read_time;
+ if (!timer_is_before(ltrt, next) && !timer_is_before(tru, ltrt)
+ && ltrt != prev_ltrt) {
+ // Can run next timer without overhead of calling timer_read_time()
+ prev_ltrt = ltrt;
+ continue;
+ }
+
uint32_t now = timer_read_time();
int32_t diff = next - now;
if (diff > (int32_t)TIMER_MIN_TRY_TICKS)
@@ -158,7 +170,7 @@ timer_dispatch_many(void)
void
timer_task(void)
{
- uint32_t now = timer_read_time();
+ uint32_t now = last_timer_read_time;
irq_disable();
if (timer_is_before(timer_repeat_until, now))
timer_repeat_until = now;