feat: add yield

This commit is contained in:
Paul Pan 2024-07-03 22:51:21 +08:00
parent 261f7dd68e
commit a2c5ba1494
5 changed files with 26 additions and 11 deletions

View File

@ -40,6 +40,7 @@ pub fn rust_main() -> ! {
setup_root_server(&fdt);
info!("Kernel Initialization Completed");
SCHEDULER.schedule();
error!("[rust_main] Should not reach here! Maybe scheduler is not working?");

View File

@ -12,6 +12,9 @@ use utils::{
pub static TID_ALLOCATOR: AtomicUsize = AtomicUsize::new(0);
// one process can run for 10 ticks
pub const TIME_TICK: usize = 10;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ThreadState {
Inactive,
@ -103,8 +106,12 @@ impl TcbObject {
self.time_tick
}
pub fn set_timetick(&mut self, timeslice: usize) {
self.time_tick = timeslice;
pub fn refill_timetick(&mut self) {
self.time_tick = if self.tid != 0 { TIME_TICK } else { 1 };
}
pub fn clear_timetick(&mut self) {
self.time_tick = 0;
}
pub fn do_tick(&mut self) {
@ -124,7 +131,7 @@ impl TcbObject {
}
pub fn handle_syscall(&mut self) {
// TODO: don't panic here, return error to user instead
// TODO: don't panic here, return error to user instead, create SysRespInfo
handle_syscall(self).unwrap();
}
}

View File

@ -1,6 +1,6 @@
use crate::objects::*;
use core::ptr::NonNull;
use log::error;
use log::{error, trace};
use spin::lazy::Lazy;
use utils::{container_of, linked_list::Link};
@ -16,9 +16,6 @@ pub static SCHEDULER: Scheduler = Scheduler::new();
// 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>,
}
@ -41,9 +38,10 @@ impl Scheduler {
pub fn schedule(&self) {
while let Some(next) = self.head.next_mut() {
if next.timetick() > 0 && next.schedulable() {
trace!("Scheduling thread {}", next.tid());
next.activate();
} else if next.timetick() == 0 {
next.set_timetick(TIME_SLICE);
next.refill_timetick();
}
// put to the end of the queue

View File

@ -14,6 +14,7 @@ pub fn handle_syscall(tcb: &mut TcbObject) -> SysResult {
trace!("handle_syscall: info={:?} cap={:?}", info, cap);
match info.label() {
Syscall::Invalid => Ok(()),
Syscall::DebugPutChar => {
if info.length() != 3 {
return Err(SysError::InvalidArgument);
@ -24,6 +25,10 @@ pub fn handle_syscall(tcb: &mut TcbObject) -> SysResult {
Ok(())
},
Syscall::Yield => {
tcb.clear_timetick();
Ok(())
},
_ => unimplemented!("handle_syscall: {:?}, {:?}", info.label(), cap),
}
}

View File

@ -10,13 +10,17 @@ _start:
la t0, msg
.loop:
lb a2, 0(t0)
beqz a2, _start
# see uapi/syscall.rs
# msg: label = DebugPutChar, length = 3
beqz a2, .yield
# msg: label = DebugPutChar(1), length = 3
# ptr: self-referential to cspace, just to create a valid cptr
syscall (1<<12 | 3), 0x0202020202020202
addi t0, t0, 1
j .loop
.yield:
# msg: label = Yield(2), length = 2
# ptr: self-referential to cspace, just to create a valid cptr
syscall (2<<12 | 2), 0x0202020202020202
j _start
.data
msg : .string "Hello, world!\n\0"