core: sched: correctly unschedule when there's no idle thread
This commit is contained in:
parent
baca419934
commit
d199865a12
59
core/sched.c
59
core/sched.c
@ -76,18 +76,45 @@ static void (*sched_cb) (kernel_pid_t active_thread,
|
|||||||
kernel_pid_t next_thread) = NULL;
|
kernel_pid_t next_thread) = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void _unschedule(thread_t *active_thread)
|
||||||
|
{
|
||||||
|
if (active_thread->status == STATUS_RUNNING) {
|
||||||
|
active_thread->status = STATUS_PENDING;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SCHED_TEST_STACK
|
||||||
|
if (*((uintptr_t *)active_thread->stack_start) !=
|
||||||
|
(uintptr_t)active_thread->stack_start) {
|
||||||
|
LOG_WARNING(
|
||||||
|
"scheduler(): stack overflow detected, pid=%" PRIkernel_pid "\n",
|
||||||
|
active_thread->pid);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef MODULE_SCHED_CB
|
||||||
|
if (sched_cb) {
|
||||||
|
sched_cb(active_thread->pid, KERNEL_PID_UNDEF);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int __attribute__((used)) sched_run(void)
|
int __attribute__((used)) sched_run(void)
|
||||||
{
|
{
|
||||||
sched_context_switch_request = 0;
|
sched_context_switch_request = 0;
|
||||||
|
|
||||||
#ifndef MODULE_CORE_IDLE_THREAD
|
|
||||||
while (!runqueue_bitcache) {
|
|
||||||
sched_arch_idle();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
thread_t *active_thread = (thread_t *)sched_active_thread;
|
thread_t *active_thread = (thread_t *)sched_active_thread;
|
||||||
|
|
||||||
|
if (!IS_USED(MODULE_CORE_IDLE_THREAD)) {
|
||||||
|
if (!runqueue_bitcache) {
|
||||||
|
if (active_thread) {
|
||||||
|
_unschedule(active_thread);
|
||||||
|
active_thread = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!runqueue_bitcache) {
|
||||||
|
sched_arch_idle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int nextrq = bitarithm_lsb(runqueue_bitcache);
|
int nextrq = bitarithm_lsb(runqueue_bitcache);
|
||||||
thread_t *next_thread = container_of(sched_runqueues[nextrq].next->next,
|
thread_t *next_thread = container_of(sched_runqueues[nextrq].next->next,
|
||||||
thread_t, rq_entry);
|
thread_t, rq_entry);
|
||||||
@ -105,26 +132,12 @@ int __attribute__((used)) sched_run(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (active_thread) {
|
if (active_thread) {
|
||||||
if (active_thread->status == STATUS_RUNNING) {
|
_unschedule(active_thread);
|
||||||
active_thread->status = STATUS_PENDING;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SCHED_TEST_STACK
|
|
||||||
if (*((uintptr_t *)active_thread->stack_start) !=
|
|
||||||
(uintptr_t)active_thread->stack_start) {
|
|
||||||
LOG_WARNING(
|
|
||||||
"scheduler(): stack overflow detected, pid=%" PRIkernel_pid "\n",
|
|
||||||
active_thread->pid);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MODULE_SCHED_CB
|
#ifdef MODULE_SCHED_CB
|
||||||
if (sched_cb) {
|
if (sched_cb) {
|
||||||
/* Use `sched_active_pid` instead of `active_thread` since after `sched_task_exit()` is
|
sched_cb(KERNEL_PID_UNDEF, next_thread->pid);
|
||||||
called `active_thread` is set to NULL while `sched_active_thread` isn't updated until
|
|
||||||
`next_thread` is scheduled*/
|
|
||||||
sched_cb(sched_active_pid, next_thread->pid);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user