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