aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2021-04-17 20:05:51 -0400
committerKevin O'Connor <kevin@koconnor.net>2021-04-18 13:12:32 -0400
commitdb0fb5d596487c9cbb0e7a8e16c6a558b13cbba2 (patch)
tree451dd477b428e7f79582d562ecbc6d688612ff8b
parent89af88d016591a53e407749a12304f5f6165b1d5 (diff)
downloadkutter-db0fb5d596487c9cbb0e7a8e16c6a558b13cbba2.tar.gz
kutter-db0fb5d596487c9cbb0e7a8e16c6a558b13cbba2.tar.xz
kutter-db0fb5d596487c9cbb0e7a8e16c6a558b13cbba2.zip
linux: Avoid calling timer_read_time() in timer_dispatch() when not needed
The timer_read_time() call can be expensive - when the next timer is definitely pending, avoid making that call. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
-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;