From 797652c2b8fe3c65c8d4ad75ebe7a29879809af4 Mon Sep 17 00:00:00 2001 From: Paul Pan Date: Sun, 16 Jun 2024 00:11:17 +0800 Subject: [PATCH] fix: scheduler: head node will never be scheduled, add a dummy head node --- kernel/src/arch/riscv/board/virt/mod.rs | 2 +- kernel/src/entry.rs | 5 ++++- kernel/src/scheduler.rs | 23 +++++++++++------------ 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/kernel/src/arch/riscv/board/virt/mod.rs b/kernel/src/arch/riscv/board/virt/mod.rs index d18526e..95c9e5a 100644 --- a/kernel/src/arch/riscv/board/virt/mod.rs +++ b/kernel/src/arch/riscv/board/virt/mod.rs @@ -1,4 +1,4 @@ -pub const TIMER_TICKS: u64 = 100_000; // 100ms +pub const TIMER_TICKS: u64 = 100_000; // devices pub const UART0_BASE: usize = 0x1000_0000; diff --git a/kernel/src/entry.rs b/kernel/src/entry.rs index d98a5d6..76319bf 100644 --- a/kernel/src/entry.rs +++ b/kernel/src/entry.rs @@ -2,7 +2,7 @@ use crate::plat::console::{set_console, ConsoleDevice, ConsoleDriver, CONSOLE}; use crate::plat::lowlevel::{Hardware, LowLevel}; use crate::plat::timer::{Timer, TimerOps}; use crate::plat::trap::{Trap, TrapOps}; -use crate::scheduler::SCHEDULER; +use crate::scheduler::{IDLE_THREAD, SCHEDULER}; use core::cell::Cell; use core::sync::atomic::{AtomicUsize, Ordering}; use fdt::Fdt; @@ -35,6 +35,9 @@ pub fn rust_main() -> ! { Trap::init(); Timer::init(); + SCHEDULER.init(); + SCHEDULER.add(&IDLE_THREAD); + SCHEDULER.schedule(); loop { diff --git a/kernel/src/scheduler.rs b/kernel/src/scheduler.rs index 13c9b9c..94586ec 100644 --- a/kernel/src/scheduler.rs +++ b/kernel/src/scheduler.rs @@ -1,18 +1,18 @@ use crate::objects::*; use core::ptr::NonNull; -use log::{error, trace}; +use log::error; use spin::lazy::Lazy; -use utils::linked_list::Link; +use utils::{container_of, linked_list::Link}; #[thread_local] -static IDLE_THREAD: Lazy = Lazy::new(|| { +pub static IDLE_THREAD: Lazy = Lazy::new(|| { let mut idle_thread = TcbObject::new(); idle_thread.configure_idle_thread(); idle_thread }); #[thread_local] -pub static SCHEDULER: Lazy = Lazy::new(|| Scheduler::new(&IDLE_THREAD)); +pub static SCHEDULER: Scheduler = Scheduler::new(); // TODO: add a shared buffer to transfer TCB between cores @@ -24,14 +24,14 @@ pub struct Scheduler { } impl Scheduler { - pub fn new(idle_thread: &TcbObject) -> Self { - // link idle_thread - idle_thread.link.set_prev(Some(NonNull::from(idle_thread))); - idle_thread.link.set_next(Some(NonNull::from(idle_thread))); + pub const fn new() -> Self { + Self { head: Link::new() } + } - Self { - head: idle_thread.link.clone(), - } + pub fn init(&self) { + let head = unsafe { Some(NonNull::from(&*container_of!(&self.head, TcbObject, link))) }; + self.head.set_next(head); + self.head.set_prev(head); } pub fn add(&self, tcb: &TcbObject) { @@ -41,7 +41,6 @@ impl Scheduler { pub fn schedule(&self) { while let Some(next) = self.head.next_mut() { if next.timetick() > 0 && next.schedulable() { - trace!("[Scheduler] Switch to {}, tick: {}", next.tid(), next.timetick()); next.activate(); } else if next.timetick() == 0 { next.set_timetick(TIME_SLICE);