rename 'event_hub' to 'timer', add doc and simplify

master
WangRunji 6 years ago
parent 0ec5ad8056
commit 086fcd4079

@ -1,93 +0,0 @@
use alloc::collections::VecDeque;
use core::cmp::{Ordering, PartialOrd};
type Time = usize;
struct Timer<T> {
time: Time,
data: T,
}
impl<T> PartialEq for Timer<T> {
fn eq(&self, other: &Self) -> bool {
self.time.eq(&other.time)
}
}
impl<T> Eq for Timer<T> {}
impl<T> PartialOrd for Timer<T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
other.time.partial_cmp(&self.time)
}
}
impl<T> Ord for Timer<T> {
fn cmp(&self, other: &Self) -> Ordering {
self.partial_cmp(&other).unwrap()
}
}
pub struct EventHub<T> {
tick: Time,
timers: VecDeque<Timer<T>>,
}
impl<T: PartialEq> EventHub<T> {
pub fn new() -> Self {
EventHub {
tick: 0,
timers: VecDeque::new(),
}
}
pub fn tick(&mut self) {
self.tick += 1;
}
pub fn pop(&mut self) -> Option<T> {
match self.timers.front() {
None => return None,
Some(timer) if timer.time != self.tick => return None,
_ => {}
};
self.timers.pop_front().map(|t| t.data)
}
pub fn push(&mut self, time_after: Time, data: T) {
//debug!("{:?} {:?}", self.tick, time_after);
let time = self.tick + time_after;
let timer = Timer { time, data };
let mut it = self.timers.iter();
let mut i : usize = 0;
loop {
let now = it.next();
if now == None {
break
};
if now.unwrap() < &timer {
break
};
i += 1;
}
self.timers.insert(i, timer);
}
#[allow(dead_code)]
pub fn get_time(&self) -> Time {
self.tick
}
pub fn remove(&mut self, data: T) {
let mut it = self.timers.iter();
let mut i : usize = 0;
loop {
let now = it.next();
if now == None {
break
};
if now.map(|t| &t.data).unwrap() == &data {
break
};
i += 1;
}
if i < self.timers.len() {
self.timers.remove(i);
}
}
}

@ -13,7 +13,7 @@ mod thread_pool;
mod processor;
pub mod scheduler;
pub mod std_thread;
mod event_hub;
mod timer;
mod interrupt;
pub use crate::thread_pool::*;

@ -3,7 +3,7 @@ use alloc::vec::Vec;
use spin::Mutex;
use log::*;
use crate::scheduler::Scheduler;
use crate::event_hub::EventHub;
use crate::timer::Timer;
struct Thread {
status: Status,
@ -38,7 +38,7 @@ pub trait Context {
pub struct ThreadPool {
threads: Vec<Mutex<Option<Thread>>>,
scheduler: Mutex<Box<Scheduler>>,
event_hub: Mutex<EventHub<Event>>,
timer: Mutex<Timer<Event>>,
}
impl ThreadPool {
@ -46,7 +46,7 @@ impl ThreadPool {
ThreadPool {
threads: new_vec_default(max_proc_num),
scheduler: Mutex::new(scheduler),
event_hub: Mutex::new(EventHub::new()),
timer: Mutex::new(Timer::new()),
}
}
@ -79,9 +79,9 @@ impl ThreadPool {
/// Return true if time slice == 0.
/// Called by timer interrupt handler.
pub fn tick(&self, tid: Tid) -> bool {
let mut event_hub = self.event_hub.lock();
event_hub.tick();
while let Some(event) = event_hub.pop() {
let mut timer = self.timer.lock();
timer.tick();
while let Some(event) = timer.pop() {
match event {
Event::Wakeup(tid) => self.set_status(tid, Status::Ready),
}
@ -133,7 +133,7 @@ impl ThreadPool {
(Status::Ready, Status::Ready) => return,
(Status::Ready, _) => self.scheduler.lock().remove(tid),
(Status::Exited(_), _) => panic!("can not set status for a exited process"),
(Status::Sleeping, Status::Exited(_)) => self.event_hub.lock().remove(Event::Wakeup(tid)),
(Status::Sleeping, Status::Exited(_)) => self.timer.lock().stop(Event::Wakeup(tid)),
(_, Status::Ready) => self.scheduler.lock().insert(tid),
_ => {}
}
@ -176,7 +176,7 @@ impl ThreadPool {
pub fn sleep(&self, tid: Tid, time: usize) {
self.set_status(tid, Status::Sleeping);
if time != 0 {
self.event_hub.lock().push(time, Event::Wakeup(tid));
self.timer.lock().start(time, Event::Wakeup(tid));
}
}

@ -0,0 +1,65 @@
//! A simple timer
use alloc::collections::VecDeque;
type Time = usize;
struct Event<T> {
time: Time,
data: T,
}
/// A simple timer using ordered dequeue
pub struct Timer<T> {
tick: Time,
timers: VecDeque<Event<T>>,
}
impl<T: PartialEq> Timer<T> {
/// Create a new timer.
pub fn new() -> Self {
Timer {
tick: 0,
timers: VecDeque::new(),
}
}
/// Called on each tick.
pub fn tick(&mut self) {
self.tick += 1;
}
/// Pop an expired timer after `tick`.
///
/// This must be called after calling `tick`,
/// and should be called multiple times until return `None`.
pub fn pop(&mut self) -> Option<T> {
match self.timers.front() {
None => return None,
Some(timer) if timer.time != self.tick => return None,
_ => {}
};
self.timers.pop_front().map(|t| t.data)
}
/// Start a timer with given time interval
pub fn start(&mut self, time_after: Time, data: T) {
//debug!("{:?} {:?}", self.tick, time_after);
let time = self.tick + time_after;
let event = Event { time, data };
let mut it = self.timers.iter();
let mut i : usize = 0;
loop {
match it.next() {
None => break,
Some(e) if e.time >= time => break,
_ => {}
}
i += 1;
}
self.timers.insert(i, event);
}
/// Stop a timer
pub fn stop(&mut self, data: T) {
if let Some(i) = self.timers.iter().position(|t| t.data == data) {
self.timers.remove(i);
}
}
}
Loading…
Cancel
Save