linux: Don't use timer_repeat_until for linux "irq" polling
Use a simpler counter system to prioritize tasks and irqs when busy. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
92fe116dc7
commit
acd94909bc
|
@ -18,8 +18,6 @@ static struct {
|
||||||
uint32_t last_read_time;
|
uint32_t last_read_time;
|
||||||
// Fields for converting from a systime to ticks
|
// Fields for converting from a systime to ticks
|
||||||
time_t start_sec;
|
time_t start_sec;
|
||||||
// Maximum absolute time that can be spent in timer_dispatch()
|
|
||||||
uint32_t timer_repeat_until;
|
|
||||||
// Time of next software timer (also used to convert from ticks to systime)
|
// Time of next software timer (also used to convert from ticks to systime)
|
||||||
uint32_t next_wake_counter;
|
uint32_t next_wake_counter;
|
||||||
struct timespec next_wake;
|
struct timespec next_wake;
|
||||||
|
@ -126,28 +124,25 @@ timer_kick(void)
|
||||||
TimerInfo.next_wake_counter = timespec_to_time(TimerInfo.next_wake);
|
TimerInfo.next_wake_counter = timespec_to_time(TimerInfo.next_wake);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TIMER_IDLE_REPEAT_TICKS timer_from_us(500)
|
#define TIMER_IDLE_REPEAT_COUNT 100
|
||||||
#define TIMER_REPEAT_TICKS timer_from_us(100)
|
#define TIMER_REPEAT_COUNT 20
|
||||||
|
|
||||||
#define TIMER_MIN_TRY_TICKS timer_from_us(2)
|
#define TIMER_MIN_TRY_TICKS timer_from_us(2)
|
||||||
#define TIMER_DEFER_REPEAT_TICKS timer_from_us(5)
|
|
||||||
|
|
||||||
// Invoke timers
|
// Invoke timers
|
||||||
static uint32_t
|
static uint32_t
|
||||||
timer_dispatch_many(void)
|
timer_dispatch_many(void)
|
||||||
{
|
{
|
||||||
uint32_t tru = TimerInfo.timer_repeat_until, prev_lrt = 0;
|
uint32_t repeat_count = TIMER_REPEAT_COUNT;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
// Run the next software timer
|
// Run the next software timer
|
||||||
uint32_t next = sched_timer_dispatch();
|
uint32_t next = sched_timer_dispatch();
|
||||||
|
|
||||||
|
repeat_count--;
|
||||||
uint32_t lrt = TimerInfo.last_read_time;
|
uint32_t lrt = TimerInfo.last_read_time;
|
||||||
if (!timer_is_before(lrt, next) && !timer_is_before(tru, lrt)
|
if (!timer_is_before(lrt, next) && repeat_count)
|
||||||
&& lrt != prev_lrt) {
|
|
||||||
// Can run next timer without overhead of calling timer_read_time()
|
// Can run next timer without overhead of calling timer_read_time()
|
||||||
prev_lrt = lrt;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t now = timer_read_time();
|
uint32_t now = timer_read_time();
|
||||||
int32_t diff = next - now;
|
int32_t diff = next - now;
|
||||||
|
@ -155,15 +150,13 @@ timer_dispatch_many(void)
|
||||||
// Schedule next timer normally.
|
// Schedule next timer normally.
|
||||||
return next;
|
return next;
|
||||||
|
|
||||||
if (unlikely(timer_is_before(tru, now))) {
|
if (unlikely(!repeat_count)) {
|
||||||
// Check if there are too many repeat timers
|
// Check if there are too many repeat timers
|
||||||
if (diff < (int32_t)(-timer_from_us(100000)))
|
if (diff < (int32_t)(-timer_from_us(100000)))
|
||||||
try_shutdown("Rescheduled timer in the past");
|
try_shutdown("Rescheduled timer in the past");
|
||||||
if (sched_tasks_busy()) {
|
if (sched_tasks_busy())
|
||||||
TimerInfo.timer_repeat_until = now + TIMER_REPEAT_TICKS;
|
return now;
|
||||||
return now + TIMER_DEFER_REPEAT_TICKS;
|
repeat_count = TIMER_IDLE_REPEAT_COUNT;
|
||||||
}
|
|
||||||
TimerInfo.timer_repeat_until = tru = now + TIMER_IDLE_REPEAT_TICKS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next timer in the past or near future - wait for it to be ready
|
// Next timer in the past or near future - wait for it to be ready
|
||||||
|
@ -172,19 +165,6 @@ timer_dispatch_many(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure timer_repeat_until doesn't wrap 32bit comparisons
|
|
||||||
void
|
|
||||||
timer_task(void)
|
|
||||||
{
|
|
||||||
uint32_t lrt = TimerInfo.last_read_time;
|
|
||||||
irq_disable();
|
|
||||||
if (timer_is_before(TimerInfo.timer_repeat_until, lrt))
|
|
||||||
TimerInfo.timer_repeat_until = lrt;
|
|
||||||
irq_enable();
|
|
||||||
}
|
|
||||||
DECL_TASK(timer_task);
|
|
||||||
|
|
||||||
// Invoke timers
|
|
||||||
static void
|
static void
|
||||||
timer_dispatch(void)
|
timer_dispatch(void)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue