Basic EventHub and Timer.

master
WangRunji 7 years ago
parent 950fe4fedc
commit 0f26f6ffd6

@ -71,21 +71,9 @@ interrupt!(com2, {
ack(IRQ_COM2); ack(IRQ_COM2);
}); });
use spin::Mutex;
// FIXME: Deadlock
//static TICK: Mutex<usize> = Mutex::new(0);
interrupt_switch!(timer, stack, rsp, { interrupt_switch!(timer, stack, rsp, {
// let mut tick = TICK.lock(); use schedule;
// *tick += 1; schedule::timer_handler(stack, &mut rsp);
// 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);
}
ack(IRQ_TIMER); ack(IRQ_TIMER);
}); });

@ -38,7 +38,7 @@ pub fn load_sfs() {
trace!("Loading programs: {:?}", files); trace!("Loading programs: {:?}", files);
// for name in files.iter().filter(|&f| f != "." && f != "..") { // 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]; static mut BUF: [u8; 64 << 12] = [0; 64 << 12];
let file = root.borrow().lookup(name.as_str()).unwrap(); let file = root.borrow().lookup(name.as_str()).unwrap();
let len = file.borrow().read_at(0, unsafe { &mut BUF }).unwrap(); let len = file.borrow().read_at(0, unsafe { &mut BUF }).unwrap();

@ -49,6 +49,7 @@ mod consts;
mod process; mod process;
mod syscall; mod syscall;
mod fs; mod fs;
mod schedule;
#[allow(dead_code)] #[allow(dead_code)]
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]

@ -95,6 +95,11 @@ pub fn sys_exit(rsp: &mut usize, error_code: ErrorCode) -> i32 {
0 0
} }
pub fn sys_sleep(rsp: &mut usize, time: usize) -> i32 {
info!("sleep: {} ticks", time);
unimplemented!()
}
pub fn add_user_process(name: impl AsRef<str>, data: &[u8]) { pub fn add_user_process(name: impl AsRef<str>, data: &[u8]) {
let mut processor = PROCESSOR.try().unwrap().lock(); let mut processor = PROCESSOR.try().unwrap().lock();
let mut mc = MC.try().unwrap().lock(); let mut mc = MC.try().unwrap().lock();

@ -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<Option<usize>> = 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<Ordering> {
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<Time>,
timers: Mutex<BinaryHeap<Timer>>,
}
impl EventHub {
fn tick(&self) {
*self.tick.lock() += 1;
let tick = *self.tick.lock();
loop {
match self.timers.lock().peek() {
None => return,
Some(timer) if timer.time != tick => return,
_ => {}
}
let timer = self.timers.lock().pop().unwrap();
(timer.handler)();
}
}
pub fn add(&self, time_after: Time, handler: TimerHandler) {
let time = self.get_time() + time_after;
self.timers.lock().push(Timer { time, handler });
}
pub fn get_time(&self) -> Time {
*self.tick.lock()
}
}

@ -31,15 +31,19 @@ pub unsafe fn syscall(tf: &TrapFrame, rsp: &mut usize, is32: bool) -> i32 {
process::sys_exit(rsp, args[0]), process::sys_exit(rsp, args[0]),
Syscall::Ucore(UCORE_SYS_GETPID) => Syscall::Ucore(UCORE_SYS_GETPID) =>
process::sys_getpid(), process::sys_getpid(),
Syscall::Ucore(UCORE_SYS_SLEEP) =>
process::sys_sleep(rsp, args[0]),
Syscall::Ucore(UCORE_SYS_GETTIME) =>
schedule::get_time(),
Syscall::Ucore(UCORE_SYS_PUTC) => Syscall::Ucore(UCORE_SYS_PUTC) =>
{ {
print!("{}", args[0] as u8 as char); print!("{}", args[0] as u8 as char);
0 0
}, }
_ => { _ => {
warn!("unknown syscall {:#x?}", id); error!("unknown syscall {:#x?}", id);
-1 -1
}, }
} }
} }

Loading…
Cancel
Save