mirror of
https://github.com/panpaul/tiny_os
synced 2024-09-20 09:45:19 +08:00
feat: add yield
This commit is contained in:
parent
261f7dd68e
commit
a2c5ba1494
@ -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?");
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
10
root/root.S
10
root/root.S
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user