From 55f407da08c0a74623bc0f053b4bc73a32eaa3b7 Mon Sep 17 00:00:00 2001 From: Matheus Date: Sun, 14 Apr 2024 12:42:43 -0300 Subject: [PATCH] scheduler: handle interruptions in sched_yield() when sleeping as to prevent lost wakeup --- kernel-src/include/kernel/scheduler.h | 1 + kernel-src/sys/scheduler.c | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/kernel-src/include/kernel/scheduler.h b/kernel-src/include/kernel/scheduler.h index 8e0c29af..98cf9173 100644 --- a/kernel-src/include/kernel/scheduler.h +++ b/kernel-src/include/kernel/scheduler.h @@ -44,6 +44,7 @@ typedef struct thread_t { bool sleepintstatus; spinlock_t sleeplock; int wakeupreason; + bool shouldexit; } thread_t; typedef struct proc_t { diff --git a/kernel-src/sys/scheduler.c b/kernel-src/sys/scheduler.c index cbeaffbb..610bd49a 100644 --- a/kernel-src/sys/scheduler.c +++ b/kernel-src/sys/scheduler.c @@ -262,6 +262,14 @@ static void yield(context_t *context) { thread_t *next = runqueuenext(sleeping ? 0x0fffffff : thread->priority); + if (sleeping && thread->shouldexit && (thread->flags & SCHED_THREAD_FLAGS_INTERRUPTIBLE)) { + sleeping = false; + next = NULL; + thread->flags &= ~(SCHED_THREAD_FLAGS_SLEEP | SCHED_THREAD_FLAGS_INTERRUPTIBLE); + thread->wakeupreason = SCHED_WAKEUP_REASON_INTERRUPTED; + spinlock_release(&thread->sleeplock); + } + if (next || sleeping) { ARCH_CONTEXT_THREADSAVE(thread, context);