scheduling

This commit is contained in:
Jack Halford 2018-06-06 18:16:50 +02:00
parent b75d97b11e
commit ba108d9e3e
7 changed files with 63 additions and 38 deletions

View file

@ -274,9 +274,9 @@ pub fn cpu_info() -> Result {
if info.has_rtm() { if info.has_rtm() {
print!(", rtm") print!(", rtm")
}; };
if info.has_qm() { // if info.has_qm() {
print!(", qm") // print!(", qm")
}; // };
if info.has_fpu_cs_ds_deprecated() { if info.has_fpu_cs_ds_deprecated() {
print!(", fpu_seg") print!(", fpu_seg")
}; };

View file

@ -57,7 +57,7 @@ interrupt!(0, pit, {
offset.1 = sum % 1_000_000; offset.1 = sum % 1_000_000;
offset.0 += sum / 1_000_000; offset.0 += sum / 1_000_000;
if sum > 1_000_000 { if sum > 1_000_000 {
fprintln!("uptime: {}s", offset.0); // fprintln!("uptime: {}s", offset.0);
} }
} }
unsafe { pic::MASTER.ack() }; unsafe { pic::MASTER.ack() };

View file

@ -43,8 +43,8 @@ pub mod memory;
/// arch specific entry points /// arch specific entry points
pub mod arch; pub mod arch;
pub use arch::x86::consts::*; pub use arch::x86::consts::*;
/// process scheduling /// concurrency management
pub mod process; pub mod scheduling;
/// uptime counting /// uptime counting
pub mod time; pub mod time;
@ -57,7 +57,7 @@ pub fn kmain() -> ! {
// vga is *not* cpu specific I think // vga is *not* cpu specific I think
vga::init(); vga::init();
process::schedule(); scheduling::schedule();
unreachable!(); unreachable!();
} }

View file

@ -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 alloc::VecDeque;
use super::*; use super::*;
// use super::process::*;
pub struct Fifo { pub struct Fifo {
list: VecDeque<Process>, list: VecDeque<Process>,
@ -17,7 +24,7 @@ impl Fifo {
} }
impl Scheduler for 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); let p = Process::new(self.next_pid, ip);
self.list.push_back(p); self.list.push_back(p);
self.next_pid += 1; self.next_pid += 1;

View file

@ -1,50 +1,27 @@
mod process;
mod fifo; mod fifo;
use spin::Mutex; use spin::Mutex;
pub use self::process::*;
lazy_static! { lazy_static! {
pub static ref SCHEDULER: Mutex<fifo::Fifo> = Mutex::new({ pub static ref SCHEDULER: Mutex<fifo::Fifo> = Mutex::new({
let init_process: u32 = self::init as *const () as u32; let init_process: u32 = self::init as *const () as u32;
let mut f = fifo::Fifo::new(); let mut f = fifo::Fifo::new();
f.add_process(init_process); f.add_task(init_process);
f 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 { pub trait Scheduler {
fn add_process(&mut self, ip: u32); fn add_task(&mut self, ip: u32);
fn next(&mut self) -> Option<Process>; fn next(&mut self) -> Option<Process>;
} }
pub fn schedule() { pub fn schedule() {
loop { loop {
if let Some(mut p) = SCHEDULER.lock().next() { if let Some(mut p) = SCHEDULER.lock().next() {
println!("executing {:#x}", p.ip); println!("executing {:#?}", p);
flush!(); flush!();
unsafe { unsafe {
SCHEDULER.force_unlock(); SCHEDULER.force_unlock();
@ -61,10 +38,12 @@ pub fn fork() -> i32 {
println!("ip = {:#x}", ip); println!("ip = {:#x}", ip);
flush!(); flush!();
unsafe { asm!("push $0" :: "r"(ip) :: "intel") }; unsafe { asm!("push $0" :: "r"(ip) :: "intel") };
SCHEDULER.lock().add_process(ip); SCHEDULER.lock().add_task(ip);
0 0
} }
pub fn sleep() {}
pub fn init() { pub fn init() {
fprintln!("init first line"); fprintln!("init first line");
// let i = self::fork(); // let i = self::fork();

View file

@ -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!();
}
}

View file

@ -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