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); setup_root_server(&fdt);
info!("Kernel Initialization Completed");
SCHEDULER.schedule(); SCHEDULER.schedule();
error!("[rust_main] Should not reach here! Maybe scheduler is not working?"); 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); 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)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ThreadState { pub enum ThreadState {
Inactive, Inactive,
@ -103,8 +106,12 @@ impl TcbObject {
self.time_tick self.time_tick
} }
pub fn set_timetick(&mut self, timeslice: usize) { pub fn refill_timetick(&mut self) {
self.time_tick = timeslice; 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) { pub fn do_tick(&mut self) {
@ -124,7 +131,7 @@ impl TcbObject {
} }
pub fn handle_syscall(&mut self) { 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(); handle_syscall(self).unwrap();
} }
} }

View File

@ -1,6 +1,6 @@
use crate::objects::*; use crate::objects::*;
use core::ptr::NonNull; use core::ptr::NonNull;
use log::error; use log::{error, trace};
use spin::lazy::Lazy; use spin::lazy::Lazy;
use utils::{container_of, linked_list::Link}; 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 // 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 { pub struct Scheduler {
head: Link<TcbObject>, head: Link<TcbObject>,
} }
@ -41,9 +38,10 @@ impl Scheduler {
pub fn schedule(&self) { pub fn schedule(&self) {
while let Some(next) = self.head.next_mut() { while let Some(next) = self.head.next_mut() {
if next.timetick() > 0 && next.schedulable() { if next.timetick() > 0 && next.schedulable() {
trace!("Scheduling thread {}", next.tid());
next.activate(); next.activate();
} else if next.timetick() == 0 { } else if next.timetick() == 0 {
next.set_timetick(TIME_SLICE); next.refill_timetick();
} }
// put to the end of the queue // 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); trace!("handle_syscall: info={:?} cap={:?}", info, cap);
match info.label() { match info.label() {
Syscall::Invalid => Ok(()),
Syscall::DebugPutChar => { Syscall::DebugPutChar => {
if info.length() != 3 { if info.length() != 3 {
return Err(SysError::InvalidArgument); return Err(SysError::InvalidArgument);
@ -24,6 +25,10 @@ pub fn handle_syscall(tcb: &mut TcbObject) -> SysResult {
Ok(()) Ok(())
}, },
Syscall::Yield => {
tcb.clear_timetick();
Ok(())
},
_ => unimplemented!("handle_syscall: {:?}, {:?}", info.label(), cap), _ => unimplemented!("handle_syscall: {:?}, {:?}", info.label(), cap),
} }
} }

View File

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