diff --git a/src/arch/x86_64/interrupt/handler.rs b/src/arch/x86_64/interrupt/handler.rs index ac2c8b7..3dd83da 100644 --- a/src/arch/x86_64/interrupt/handler.rs +++ b/src/arch/x86_64/interrupt/handler.rs @@ -71,21 +71,9 @@ interrupt!(com2, { ack(IRQ_COM2); }); -use spin::Mutex; -// FIXME: Deadlock -//static TICK: Mutex = Mutex::new(0); - interrupt_switch!(timer, stack, rsp, { -// let mut tick = TICK.lock(); -// *tick += 1; -// let tick = *tick; - static mut tick: usize = 0; - unsafe{ tick += 1; } - if tick % 100 == 0 { - info!("\nInterupt: Timer\ntick = {}", tick); - use process; - process::schedule(&mut rsp); - } + use schedule; + schedule::timer_handler(stack, &mut rsp); ack(IRQ_TIMER); }); diff --git a/src/fs.rs b/src/fs.rs index e14fe72..8081805 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -38,7 +38,7 @@ pub fn load_sfs() { trace!("Loading programs: {:?}", files); // for name in files.iter().filter(|&f| f != "." && f != "..") { - for name in files.iter().filter(|&f| f == "forktest") { + for name in files.iter().filter(|&f| f == "sleep") { static mut BUF: [u8; 64 << 12] = [0; 64 << 12]; let file = root.borrow().lookup(name.as_str()).unwrap(); let len = file.borrow().read_at(0, unsafe { &mut BUF }).unwrap(); diff --git a/src/lib.rs b/src/lib.rs index 3b45caf..f0e614d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -49,6 +49,7 @@ mod consts; mod process; mod syscall; mod fs; +mod schedule; #[allow(dead_code)] #[cfg(target_arch = "x86_64")] diff --git a/src/process/mod.rs b/src/process/mod.rs index fe93c1f..f4af443 100644 --- a/src/process/mod.rs +++ b/src/process/mod.rs @@ -95,6 +95,11 @@ pub fn sys_exit(rsp: &mut usize, error_code: ErrorCode) -> i32 { 0 } +pub fn sys_sleep(rsp: &mut usize, time: usize) -> i32 { + info!("sleep: {} ticks", time); + unimplemented!() +} + pub fn add_user_process(name: impl AsRef, data: &[u8]) { let mut processor = PROCESSOR.try().unwrap().lock(); let mut mc = MC.try().unwrap().lock(); diff --git a/src/schedule.rs b/src/schedule.rs new file mode 100644 index 0000000..80bf63a --- /dev/null +++ b/src/schedule.rs @@ -0,0 +1,89 @@ +use spin::Mutex; +use alloc::BinaryHeap; +use arch::interrupt::TrapFrame; +use core::cmp::{Ordering, PartialOrd}; + +pub fn get_time() -> i32 { + info!("get_time:"); + EVENT_HUB.get_time() as i32 +} + +pub fn timer_handler(tf: &TrapFrame, rsp: &mut usize) { + // Store rsp to global for `schedule` + *RSP.lock() = Some(*rsp); + + EVENT_HUB.tick(); + + // Take rsp from global + *rsp = RSP.lock().take().unwrap(); +} + +static RSP: Mutex> = Mutex::new(None); + +fn schedule() { + info!("Schedule at time {}", EVENT_HUB.get_time()); + use process; + process::schedule(RSP.lock().as_mut().unwrap()); + + // Repeat + EVENT_HUB.add(100, schedule); +} + +lazy_static! { + static ref EVENT_HUB: EventHub = { + let e = EventHub::default(); + e.add(100, schedule); + info!("EventHub: init"); + e + }; +} + +type Time = usize; +type TimerHandler = fn(); + +#[derive(Debug, Eq, PartialEq)] +struct Timer { + time: Time, + handler: TimerHandler, +} + +impl PartialOrd for Timer { + fn partial_cmp(&self, other: &Self) -> Option { + other.time.partial_cmp(&self.time) + } +} + +impl Ord for Timer { + fn cmp(&self, other: &Self) -> Ordering { + self.partial_cmp(&other).unwrap() + } +} + +#[derive(Default)] +struct EventHub { + tick: Mutex