From ba108d9e3e92188cc07215cb45ff75a86063f65d Mon Sep 17 00:00:00 2001 From: Jack Halford Date: Wed, 6 Jun 2018 18:16:50 +0200 Subject: [PATCH] scheduling --- kernel-rs/src/arch/x86/devices/cpu.rs | 6 +-- kernel-rs/src/arch/x86/interrupt/irq.rs | 2 +- kernel-rs/src/lib.rs | 6 +-- kernel-rs/src/{process => scheduling}/fifo.rs | 9 ++++- kernel-rs/src/{process => scheduling}/mod.rs | 39 +++++-------------- kernel-rs/src/scheduling/process.rs | 33 ++++++++++++++++ kernel-rs/src/scheduling/sleep.rs | 6 +++ 7 files changed, 63 insertions(+), 38 deletions(-) rename kernel-rs/src/{process => scheduling}/fifo.rs (61%) rename kernel-rs/src/{process => scheduling}/mod.rs (54%) create mode 100644 kernel-rs/src/scheduling/process.rs create mode 100644 kernel-rs/src/scheduling/sleep.rs diff --git a/kernel-rs/src/arch/x86/devices/cpu.rs b/kernel-rs/src/arch/x86/devices/cpu.rs index 35c56a7c..079db7d5 100644 --- a/kernel-rs/src/arch/x86/devices/cpu.rs +++ b/kernel-rs/src/arch/x86/devices/cpu.rs @@ -274,9 +274,9 @@ pub fn cpu_info() -> Result { if info.has_rtm() { print!(", rtm") }; - if info.has_qm() { - print!(", qm") - }; + // if info.has_qm() { + // print!(", qm") + // }; if info.has_fpu_cs_ds_deprecated() { print!(", fpu_seg") }; diff --git a/kernel-rs/src/arch/x86/interrupt/irq.rs b/kernel-rs/src/arch/x86/interrupt/irq.rs index 81817b7b..7385a455 100644 --- a/kernel-rs/src/arch/x86/interrupt/irq.rs +++ b/kernel-rs/src/arch/x86/interrupt/irq.rs @@ -57,7 +57,7 @@ interrupt!(0, pit, { offset.1 = sum % 1_000_000; offset.0 += sum / 1_000_000; if sum > 1_000_000 { - fprintln!("uptime: {}s", offset.0); + // fprintln!("uptime: {}s", offset.0); } } unsafe { pic::MASTER.ack() }; diff --git a/kernel-rs/src/lib.rs b/kernel-rs/src/lib.rs index 19039bac..f323022c 100644 --- a/kernel-rs/src/lib.rs +++ b/kernel-rs/src/lib.rs @@ -43,8 +43,8 @@ pub mod memory; /// arch specific entry points pub mod arch; pub use arch::x86::consts::*; -/// process scheduling -pub mod process; +/// concurrency management +pub mod scheduling; /// uptime counting pub mod time; @@ -57,7 +57,7 @@ pub fn kmain() -> ! { // vga is *not* cpu specific I think vga::init(); - process::schedule(); + scheduling::schedule(); unreachable!(); } diff --git a/kernel-rs/src/process/fifo.rs b/kernel-rs/src/scheduling/fifo.rs similarity index 61% rename from kernel-rs/src/process/fifo.rs rename to kernel-rs/src/scheduling/fifo.rs index c5be7b85..5f64228f 100644 --- a/kernel-rs/src/process/fifo.rs +++ b/kernel-rs/src/scheduling/fifo.rs @@ -1,6 +1,13 @@ +//! simple first come first serve scheduling algorithm +//! unsound for everyday use, a process can decide to +//! hijack the cpu, also it only allows for terminating +//! processes... +//! however it's stupid simple to implement! + use alloc::VecDeque; use super::*; +// use super::process::*; pub struct Fifo { list: VecDeque, @@ -17,7 +24,7 @@ impl Fifo { } impl Scheduler for Fifo { - fn add_process(&mut self, ip: u32) { + fn add_task(&mut self, ip: u32) { let p = Process::new(self.next_pid, ip); self.list.push_back(p); self.next_pid += 1; diff --git a/kernel-rs/src/process/mod.rs b/kernel-rs/src/scheduling/mod.rs similarity index 54% rename from kernel-rs/src/process/mod.rs rename to kernel-rs/src/scheduling/mod.rs index af270b35..e1708787 100644 --- a/kernel-rs/src/process/mod.rs +++ b/kernel-rs/src/scheduling/mod.rs @@ -1,50 +1,27 @@ +mod process; mod fifo; + use spin::Mutex; +pub use self::process::*; lazy_static! { pub static ref SCHEDULER: Mutex = Mutex::new({ let init_process: u32 = self::init as *const () as u32; let mut f = fifo::Fifo::new(); - f.add_process(init_process); + f.add_task(init_process); f }); } -// lazy_static! { -// static ref SCHEDULER: self::Scheduler = self::Scheduler { -// list: Mutex::new(VecDeque::new()) -// }; -// } - -#[derive(Debug)] -pub struct Process { - // this is eip right now - // this will be an elf blob later - pid: i32, - ip: u32, -} - -impl Process { - pub fn new(pid: i32, ip: u32) -> Process { - Process { pid, ip } - } - - pub unsafe fn execute(&mut self) { - let scheduler_loop = schedule as *const () as u32; - asm!("push $0; push $1; ret" :: "r"(scheduler_loop) ,"r"(self.ip) :: "volatile", "intel"); - unreachable!(); - } -} - pub trait Scheduler { - fn add_process(&mut self, ip: u32); + fn add_task(&mut self, ip: u32); fn next(&mut self) -> Option; } pub fn schedule() { loop { if let Some(mut p) = SCHEDULER.lock().next() { - println!("executing {:#x}", p.ip); + println!("executing {:#?}", p); flush!(); unsafe { SCHEDULER.force_unlock(); @@ -61,10 +38,12 @@ pub fn fork() -> i32 { println!("ip = {:#x}", ip); flush!(); unsafe { asm!("push $0" :: "r"(ip) :: "intel") }; - SCHEDULER.lock().add_process(ip); + SCHEDULER.lock().add_task(ip); 0 } +pub fn sleep() {} + pub fn init() { fprintln!("init first line"); // let i = self::fork(); diff --git a/kernel-rs/src/scheduling/process.rs b/kernel-rs/src/scheduling/process.rs new file mode 100644 index 00000000..e09ac959 --- /dev/null +++ b/kernel-rs/src/scheduling/process.rs @@ -0,0 +1,33 @@ +#[derive(Debug)] +pub enum State { + Running, + Ready, + Sleeping(u32), + Blocked(), +} + +#[derive(Debug)] +pub struct Process { + pid: i32, + // this is eip right now + // this will be an elf blob later + ip: u32, + state: State, +} + +impl Process { + pub fn new(pid: i32, ip: u32) -> Process { + Process { + pid, + ip, + state: State::Ready, + } + } + + pub unsafe fn execute(&mut self) { + use super::schedule; + let scheduler_loop = schedule as *const () as u32; + asm!("push $0; push $1; ret" :: "r"(scheduler_loop) ,"r"(self.ip) :: "volatile", "intel"); + unreachable!(); + } +} diff --git a/kernel-rs/src/scheduling/sleep.rs b/kernel-rs/src/scheduling/sleep.rs new file mode 100644 index 00000000..ceb57610 --- /dev/null +++ b/kernel-rs/src/scheduling/sleep.rs @@ -0,0 +1,6 @@ +//! sleeping processing are stored in a delta queue +//! separate from other scheduling structures: this +//! way the scheduling algorithms don't have to worry about +//! managing these +//! +//! inspired from https://wiki.osdev.org/Blocking_Process