From 086fcd4079204690f3b07002e466ed1ba05449bd Mon Sep 17 00:00:00 2001 From: WangRunji Date: Mon, 28 Jan 2019 13:47:51 +0800 Subject: [PATCH] rename 'event_hub' to 'timer', add doc and simplify --- crate/thread/src/event_hub.rs | 93 --------------------------------- crate/thread/src/lib.rs | 2 +- crate/thread/src/thread_pool.rs | 16 +++--- crate/thread/src/timer.rs | 65 +++++++++++++++++++++++ 4 files changed, 74 insertions(+), 102 deletions(-) delete mode 100644 crate/thread/src/event_hub.rs create mode 100644 crate/thread/src/timer.rs diff --git a/crate/thread/src/event_hub.rs b/crate/thread/src/event_hub.rs deleted file mode 100644 index 62d2cec..0000000 --- a/crate/thread/src/event_hub.rs +++ /dev/null @@ -1,93 +0,0 @@ -use alloc::collections::VecDeque; -use core::cmp::{Ordering, PartialOrd}; - -type Time = usize; - -struct Timer { - time: Time, - data: T, -} - -impl PartialEq for Timer { - fn eq(&self, other: &Self) -> bool { - self.time.eq(&other.time) - } -} - -impl Eq for Timer {} - -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() - } -} - -pub struct EventHub { - tick: Time, - timers: VecDeque>, -} - -impl EventHub { - pub fn new() -> Self { - EventHub { - tick: 0, - timers: VecDeque::new(), - } - } - pub fn tick(&mut self) { - self.tick += 1; - } - pub fn pop(&mut self) -> Option { - 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); - } - } -} \ No newline at end of file diff --git a/crate/thread/src/lib.rs b/crate/thread/src/lib.rs index bd0d394..af97063 100644 --- a/crate/thread/src/lib.rs +++ b/crate/thread/src/lib.rs @@ -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::*; diff --git a/crate/thread/src/thread_pool.rs b/crate/thread/src/thread_pool.rs index 7043b55..8d16de6 100644 --- a/crate/thread/src/thread_pool.rs +++ b/crate/thread/src/thread_pool.rs @@ -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>>, scheduler: Mutex>, - event_hub: Mutex>, + timer: Mutex>, } 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)); } } diff --git a/crate/thread/src/timer.rs b/crate/thread/src/timer.rs new file mode 100644 index 0000000..9854f14 --- /dev/null +++ b/crate/thread/src/timer.rs @@ -0,0 +1,65 @@ +//! A simple timer + +use alloc::collections::VecDeque; + +type Time = usize; + +struct Event { + time: Time, + data: T, +} + +/// A simple timer using ordered dequeue +pub struct Timer { + tick: Time, + timers: VecDeque>, +} + +impl Timer { + /// 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 { + 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); + } + } +} \ No newline at end of file