Skip to content

Commit

Permalink
core: sched: correctly unschedule when there's no idle thread
Browse files Browse the repository at this point in the history
  • Loading branch information
kaspar030 committed Jun 17, 2020
1 parent bf156f3 commit d73879e
Showing 1 changed file with 34 additions and 20 deletions.
54 changes: 34 additions & 20 deletions core/sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,18 +76,45 @@ static void (*sched_cb) (kernel_pid_t active_thread,
kernel_pid_t next_thread) = NULL;
#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)
{
sched_context_switch_request = 0;
thread_t *active_thread = (thread_t *)sched_active_thread;

#ifndef MODULE_CORE_IDLE_THREAD
while (!runqueue_bitcache) {
sched_arch_idle();
if (!runqueue_bitcache) {
if (active_thread) {
// unschedule
active_thread = NULL;
}

while (!runqueue_bitcache) {
sched_arch_idle();
}
}
#endif

thread_t *active_thread = (thread_t *)sched_active_thread;

int nextrq = bitarithm_lsb(runqueue_bitcache);
thread_t *next_thread = container_of(sched_runqueues[nextrq].next->next,
thread_t, rq_entry);
Expand All @@ -105,26 +132,13 @@ int __attribute__((used)) sched_run(void)
}

if (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
_unschedule(active_thread);
active_thread = NULL;
}

#ifdef MODULE_SCHED_CB
if (sched_cb) {
/* Use `sched_active_pid` instead of `active_thread` since after `sched_task_exit()` is
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);
sched_cb(KERNEL_PID_UNDEF, next_thread->pid);
}
#endif

Expand Down

0 comments on commit d73879e

Please sign in to comment.