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);
|
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?");
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
10
root/root.S
10
root/root.S
@ -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"
|
||||||
|
Loading…
Reference in New Issue
Block a user