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 <andrew.j.ross@intel.com>
This commit is contained in:
Andy Ross 2018-08-23 11:31:50 -07:00 committed by Anas Nashif
commit 9ecc4ead68
2 changed files with 14 additions and 0 deletions

View file

@ -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);
}

View file

@ -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)