From 9f4a804e30df5ab3e8bb9d95d6bd870945f973c2 Mon Sep 17 00:00:00 2001 From: Paul Pan Date: Thu, 29 Aug 2024 20:41:34 +0800 Subject: [PATCH] feat: kernel/scheduler: skip idle thread if there are any other threads available to run --- kernel/src/scheduler.rs | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/kernel/src/scheduler.rs b/kernel/src/scheduler.rs index 314e131..91349c0 100644 --- a/kernel/src/scheduler.rs +++ b/kernel/src/scheduler.rs @@ -2,7 +2,7 @@ use crate::objects::*; use core::sync::atomic::AtomicPtr; use log::{error, trace}; use spin::lazy::Lazy; -use tcb::SCHED_QUEUE_LINK_ID; +use tcb::{ThreadState, SCHED_QUEUE_LINK_ID}; use utils::{container_of_mut, linked_list::Link}; #[thread_local] @@ -38,10 +38,29 @@ impl Scheduler { self.head.prepend(tcb); } + pub fn add_next(&self, tcb: &TcbObject) { + self.head.append(tcb); + } + pub fn schedule(&self) { + let mut idle_found = false; + while let Some(next) = self.head.next_mut() { - if next.timetick() > 0 && next.schedulable() { - trace!("Scheduling thread {}", next.tid()); + if next.state() == ThreadState::Idle { + debug_assert!(next.tid() == 0, "IDLE thread should have TID 0"); + + if !idle_found { + // we are meeting the idle thread for the first time, bypass it + idle_found = true; + } else { + // no other thread could be scheduled + trace!("[Scheduler] Scheduling IDLE thread"); + next.refill_timetick(); + next.activate(); + } + } else if next.timetick() > 0 && next.schedulable() { + trace!("[Scheduler] Scheduling thread {}", next.tid()); + idle_found = false; next.activate(); } else if next.timetick() == 0 { next.refill_timetick();