aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/avr/timer.c2
-rw-r--r--src/generic/armcm_timer.c2
-rw-r--r--src/generic/timer_irq.c2
-rw-r--r--src/linux/timer.c2
-rw-r--r--src/sched.c16
-rw-r--r--src/sched.h2
6 files changed, 15 insertions, 11 deletions
diff --git a/src/avr/timer.c b/src/avr/timer.c
index fb8738cc..d306b721 100644
--- a/src/avr/timer.c
+++ b/src/avr/timer.c
@@ -197,7 +197,7 @@ ISR(TIMER1_COMPA_vect)
uint16_t now = timer_get();
if ((int16_t)(next - now) < (int16_t)(-timer_from_us(1000)))
try_shutdown("Rescheduled timer in the past");
- if (sched_tasks_busy()) {
+ if (sched_check_set_tasks_busy()) {
timer_repeat_set(now + TIMER_REPEAT_TICKS);
next = now + TIMER_DEFER_REPEAT_TICKS;
goto done;
diff --git a/src/generic/armcm_timer.c b/src/generic/armcm_timer.c
index ef38680a..e7708180 100644
--- a/src/generic/armcm_timer.c
+++ b/src/generic/armcm_timer.c
@@ -137,7 +137,7 @@ timer_dispatch_many(void)
// Check if there are too many repeat timers
if (diff < (int32_t)(-timer_from_us(1000)))
try_shutdown("Rescheduled timer in the past");
- if (sched_tasks_busy()) {
+ if (sched_check_set_tasks_busy()) {
timer_repeat_until = now + TIMER_REPEAT_TICKS;
return TIMER_DEFER_REPEAT_TICKS;
}
diff --git a/src/generic/timer_irq.c b/src/generic/timer_irq.c
index 40e9336b..7c2e871b 100644
--- a/src/generic/timer_irq.c
+++ b/src/generic/timer_irq.c
@@ -55,7 +55,7 @@ timer_dispatch_many(void)
// Check if there are too many repeat timers
if (diff < (int32_t)(-timer_from_us(1000)))
try_shutdown("Rescheduled timer in the past");
- if (sched_tasks_busy()) {
+ if (sched_check_set_tasks_busy()) {
timer_repeat_until = now + TIMER_REPEAT_TICKS;
return now + TIMER_DEFER_REPEAT_TICKS;
}
diff --git a/src/linux/timer.c b/src/linux/timer.c
index 21be0131..8eda62a5 100644
--- a/src/linux/timer.c
+++ b/src/linux/timer.c
@@ -152,7 +152,7 @@ timer_dispatch(void)
// Check if there are too many repeat timers
if (diff < (int32_t)(-timer_from_us(100000)))
try_shutdown("Rescheduled timer in the past");
- if (sched_tasks_busy())
+ if (sched_check_set_tasks_busy())
return;
repeat_count = TIMER_IDLE_REPEAT_COUNT;
}
diff --git a/src/sched.c b/src/sched.c
index 44cce558..51d159bc 100644
--- a/src/sched.c
+++ b/src/sched.c
@@ -1,6 +1,6 @@
// Basic scheduling functions and startup/shutdown code.
//
-// Copyright (C) 2016-2021 Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2016-2024 Kevin O'Connor <kevin@koconnor.net>
//
// This file may be distributed under the terms of the GNU GPLv3 license.
@@ -19,7 +19,7 @@ static struct timer periodic_timer, sentinel_timer, deleted_timer;
static struct {
struct timer *timer_list, *last_insert;
- int8_t tasks_status;
+ int8_t tasks_status, tasks_busy;
uint8_t shutdown_status, shutdown_reason;
} SchedStatus = {.timer_list = &periodic_timer, .last_insert = &periodic_timer};
@@ -205,11 +205,15 @@ sched_wake_tasks(void)
SchedStatus.tasks_status = TS_REQUESTED;
}
-// Check if tasks need to be run
+// Check if tasks busy (called from low-level timer dispatch code)
uint8_t
-sched_tasks_busy(void)
+sched_check_set_tasks_busy(void)
{
- return SchedStatus.tasks_status >= TS_REQUESTED;
+ // Return busy if tasks never idle between two consecutive calls
+ if (SchedStatus.tasks_busy >= TS_REQUESTED)
+ return 1;
+ SchedStatus.tasks_busy = SchedStatus.tasks_status;
+ return 0;
}
// Note that a task is ready to run
@@ -243,7 +247,7 @@ run_tasks(void)
irq_disable();
if (SchedStatus.tasks_status != TS_REQUESTED) {
// Sleep processor (only run timers) until tasks woken
- SchedStatus.tasks_status = TS_IDLE;
+ SchedStatus.tasks_status = SchedStatus.tasks_busy = TS_IDLE;
do {
irq_wait();
} while (SchedStatus.tasks_status != TS_REQUESTED);
diff --git a/src/sched.h b/src/sched.h
index 0a2bdc4b..9ec96631 100644
--- a/src/sched.h
+++ b/src/sched.h
@@ -31,7 +31,7 @@ void sched_del_timer(struct timer *del);
unsigned int sched_timer_dispatch(void);
void sched_timer_reset(void);
void sched_wake_tasks(void);
-uint8_t sched_tasks_busy(void);
+uint8_t sched_check_set_tasks_busy(void);
void sched_wake_task(struct task_wake *w);
uint8_t sched_check_wake(struct task_wake *w);
uint8_t sched_is_shutdown(void);