scheduling
This commit is contained in:
parent
b75d97b11e
commit
ba108d9e3e
7 changed files with 63 additions and 38 deletions
|
|
@ -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")
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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() };
|
||||
|
|
|
|||
|
|
@ -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!();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<Process>,
|
||||
|
|
@ -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;
|
||||
|
|
@ -1,50 +1,27 @@
|
|||
mod process;
|
||||
mod fifo;
|
||||
|
||||
use spin::Mutex;
|
||||
pub use self::process::*;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref SCHEDULER: Mutex<fifo::Fifo> = 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<Process>;
|
||||
}
|
||||
|
||||
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();
|
||||
33
kernel-rs/src/scheduling/process.rs
Normal file
33
kernel-rs/src/scheduling/process.rs
Normal 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!();
|
||||
}
|
||||
}
|
||||
6
kernel-rs/src/scheduling/sleep.rs
Normal file
6
kernel-rs/src/scheduling/sleep.rs
Normal 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
|
||||
Loading…
Reference in a new issue