feat: scheduler: rewrite

This commit is contained in:
Paul Pan 2024-05-20 16:15:36 +08:00
parent 8897e6467c
commit 5d5c18592f
3 changed files with 62 additions and 16 deletions

View File

@ -2,6 +2,7 @@ use crate::plat::console::{set_console, ConsoleDevice, ConsoleDriver, CONSOLE};
use crate::plat::lowlevel::{Hardware, LowLevel}; use crate::plat::lowlevel::{Hardware, LowLevel};
use crate::plat::timer::{Timer, TimerOps}; use crate::plat::timer::{Timer, TimerOps};
use crate::plat::trap::{Trap, TrapOps}; use crate::plat::trap::{Trap, TrapOps};
use crate::scheduler::SCHEDULER;
use core::cell::Cell; use core::cell::Cell;
use fdt::Fdt; use fdt::Fdt;
use log::{debug, error, info, warn}; use log::{debug, error, info, warn};
@ -28,7 +29,8 @@ pub fn rust_main() -> ! {
Trap::init(); Trap::init();
Timer::init(); Timer::init();
Hardware::enable_interrupt();
SCHEDULER.schedule();
loop { loop {
let data = CONSOLE.lock().try_read(); let data = CONSOLE.lock().try_read();

59
kernel/src/scheduler.rs Normal file
View File

@ -0,0 +1,59 @@
use crate::objects::tcb::TcbObject;
use core::ptr::NonNull;
use log::error;
use spin::lazy::Lazy;
use utils::linked_list::Link;
#[thread_local]
static IDLE_THREAD: Lazy<TcbObject> = Lazy::new(|| {
let mut idle_thread = TcbObject::new();
idle_thread.configure_idle_thread();
idle_thread
});
#[thread_local]
pub static SCHEDULER: Lazy<Scheduler> = Lazy::new(|| Scheduler::new(&IDLE_THREAD));
// TODO: add a shared buffer to transfer TCB between cores
// one process can run for 10 ticks
pub const TIME_SLICE: usize = 10;
pub struct Scheduler {
head: Link<TcbObject>,
}
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)));
Self {
head: idle_thread.link.clone(),
}
}
pub fn add(&self, tcb: &TcbObject) {
self.head.prepend(tcb);
}
pub fn schedule(&self) {
while let Some(next) = self.head.next_mut() {
// TODO: also need to check whether it is schedulable
if next.timeslice() > 0 {
// Available to run, activate it
next.activate();
} else if next.timeslice() == 0 {
// No time left, refill timeslice and move to the end of the queue
next.set_timeslice(TIME_SLICE);
}
// put to the end of the queue
next.link.detach();
self.head.prepend(next);
}
error!("[Scheduler] No thread to schedule! Where is IDLE thread?");
}
}

View File

@ -1,15 +0,0 @@
pub static SCHEDULER: Scheduler = Scheduler::new();
pub struct Scheduler {}
impl Scheduler {
pub const fn new() -> Self {
// TODO: implement Scheduler::new
Self {}
}
#[inline(never)]
pub fn schedule(&self) {
todo!("Scheduler::schedule");
}
}