parent
950fe4fedc
commit
0f26f6ffd6
@ -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()
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue