From 9ecc4ead68336a181d6e90f9f4f370fb6cc6d1f6 Mon Sep 17 00:00:00 2001 From: Andy Ross Date: Thu, 23 Aug 2018 11:31:50 -0700 Subject: [PATCH] sched: Properly account for timeslicing in tickless mode When adding a new runnable thread in tickless mode, we need to detect whether it will timeslice with the running thread and reset the timer, otherwise it won't get any CPU time until the next interrupt fires at some indeterminate time in the future. This fixes the specific bug discussed in #7193, but the broader problem of tickless and timeslicing interacting badly remains. The code as it exists needs some rework to avoid all the #ifdef mess. Signed-off-by: Andy Ross --- kernel/include/ksched.h | 5 +++++ kernel/sched.c | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/kernel/include/ksched.h b/kernel/include/ksched.h index 9983625ad79..4954e6af4c5 100644 --- a/kernel/include/ksched.h +++ b/kernel/include/ksched.h @@ -47,6 +47,7 @@ void *_get_next_switch_handle(void *interrupted); struct k_thread *_find_first_thread_to_unpend(_wait_q_t *wait_q, struct k_thread *from); void idle(void *a, void *b, void *c); +void z_reset_timeslice(void); /* find which one is the next thread to run */ /* must be called with interrupts locked */ @@ -222,6 +223,10 @@ static inline void _ready_thread(struct k_thread *thread) _add_thread_to_ready_q(thread); } +#if defined(CONFIG_TICKLESS_KERNEL) && !defined(CONFIG_SMP) + z_reset_timeslice(); +#endif + sys_trace_thread_ready(thread); } diff --git a/kernel/sched.c b/kernel/sched.c index 108f5102add..729e25dd1f1 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -632,6 +632,15 @@ int _is_thread_time_slicing(struct k_thread *thread) return ret; } +#ifdef CONFIG_TICKLESS_KERNEL +void z_reset_timeslice(void) +{ + if (_is_thread_time_slicing(_get_next_ready_thread())) { + _set_time(_time_slice_duration); + } +} +#endif + /* Must be called with interrupts locked */ /* Should be called only immediately before a thread switch */ void _update_time_slice_before_swap(void)