From e870e4cb03a92bd3e603344516a33b24352fb079 Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Sat, 28 Oct 2023 13:57:17 +0800 Subject: [PATCH] 1 --- src/lib.rs | 6 +- src/timer.rs | 2 +- src/xtimer.rs | 465 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 469 insertions(+), 4 deletions(-) create mode 100644 src/xtimer.rs diff --git a/src/lib.rs b/src/lib.rs index 1d94eff..4bc4ac0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,5 @@ -mod timer; -mod listhead; +pub mod xtimer; +pub mod listhead; -pub use timer::Timer; +pub use xtimer::XTimer; pub use listhead::ListHead; diff --git a/src/timer.rs b/src/timer.rs index 86da009..b02b11e 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -19,7 +19,7 @@ const TVN_MASK: usize = TVN_SIZE - 1; const TVR_MASK: usize = TVR_SIZE - 1; pub type TimerAttacherRp = Rc::>; -pub type TimerWp = Weak::>>; +pub type XTimerWp = Weak::>>; pub type TimerCb = Box::>>)>; type TimerListListHeadRp = Rc::>>; type TimerListRp = Rc::>; diff --git a/src/xtimer.rs b/src/xtimer.rs new file mode 100644 index 0000000..698f2f1 --- /dev/null +++ b/src/xtimer.rs @@ -0,0 +1,465 @@ +use std::rc::{Rc, Weak}; +use std::cell::RefCell; +use std::any::Any; +use std::cmp; +use r9_macro::SharedFromSelf; +use r9_macro_derive::SharedFromSelf; + +/* +use proc_macro::TokenStream; +use quote::quote; +use syn; + */ + +const TVN_BITS: usize = 6; +const TVR_BITS: usize = 8; +const TVN_SIZE: usize = 1 << TVN_BITS; +const TVR_SIZE: usize = 1 << TVR_BITS; +const TVN_MASK: usize = TVN_SIZE - 1; +const TVR_MASK: usize = TVR_SIZE - 1; + +pub type XTimerAttacherRp = Rc::>; +pub type XTimerWp = Weak::>>; +pub type TimerCb = Box::>>)>; +type TimerListListHeadRp = Rc::>>; +type TimerListRp = Rc::>; +type TimerListWp = Weak::>; + +pub enum TimerEvent { + Exec, + Delete, + Destory, + Custom(i32) +} + +pub struct XTimerAttacher { + timers: TimerListListHeadRp, +} + +enum TimerType { + Timeout, + Interval +} + +impl Default for TimerType { + + fn default() -> Self + { + return TimerType::Timeout; + } + +} + +#[derive(Default)] +pub struct TimerList { + holder: TimerListRp, + wp: Rc::, + timer_entry: TimerListListHeadRp, + attach_entry: TimerListListHeadRp, + timer_type: TimerType, + expire_time: i32, + expires: i64, + + cb: Option, +} + +#[derive(SharedFromSelf)] +pub struct XTimer { + free_timer_num: i32, + free_timer_list: TimerListListHeadRp, + running_timer: TimerListWp, + timer_tick: i64, + get_tick_count: fn () -> i64, + cache_timer_num: i32, + work_list: TimerListListHeadRp, + tv1: [TimerListListHeadRp; TVR_SIZE], + tv2: [TimerListListHeadRp; TVN_SIZE], + tv3: [TimerListListHeadRp; TVN_SIZE], + tv4: [TimerListListHeadRp; TVN_SIZE], + tv5: [TimerListListHeadRp; TVN_SIZE], + _self_wp: Weak::>, +} + +impl XTimer { + + pub fn init(mut self, + get_tick_count: fn () -> i64, + gctime: i32, + cache_timer_num: i32) { + self.get_tick_count = get_tick_count; + self.cache_timer_num = cache_timer_num; + self.free_timer_num = 0; + self.mut_traverse_timer_list( + &mut |timer_list: &mut TimerListListHeadRp| { + *timer_list = crate::ListHead::::new_head(); + }); + self.timer_tick = (self.get_tick_count)(); + { + let self_wp = self.shared_from_self(); + let cb = Box::new( + move |event: TimerEvent, args: Option>>| { + self_wp.borrow_mut().gc_timer(event, args); + } + ); + self.set_interval(gctime, cb); + } + } + + fn traverse_timer_list(&self, cb: &mut dyn FnMut (&TimerListListHeadRp)) { + (*cb)(&self.work_list); + let mut for_each_cb = |tv: &[TimerListListHeadRp]| { + for i in 0..tv.len() { + (*cb)(&tv[i]); + } + }; + for_each_cb(&self.tv1); + for_each_cb(&self.tv2); + for_each_cb(&self.tv3); + for_each_cb(&self.tv4); + for_each_cb(&self.tv5); + } + + fn mut_traverse_timer_list(&mut self, cb: &mut dyn FnMut (&mut TimerListListHeadRp)) { + (*cb)(&mut self.work_list); + let mut for_each_cb = |tv: &mut [TimerListListHeadRp]| { + for i in 0..tv.len() { + (*cb)(&mut tv[i]); + } + }; + for_each_cb(&mut self.tv1); + for_each_cb(&mut self.tv2); + for_each_cb(&mut self.tv3); + for_each_cb(&mut self.tv4); + for_each_cb(&mut self.tv5); + } + + pub fn uninit(&mut self) { + self.clear(); + } + + fn clear(&mut self) { + let free_timer = |head: &TimerListListHeadRp| { + while !head.borrow().empty() { + let timer = &head.borrow().first_entry().upgrade().unwrap(); + self.detach_timer(timer); + if timer.borrow().attach_entry.borrow().empty() { + timer.borrow().attach_entry.borrow_mut().del_init(); + } + } + }; + self.traverse_timer_list( + &mut |timer_list: &TimerListListHeadRp| { + free_timer(timer_list); + }); + } + + fn new_timer_list(&mut self) -> Rc::> { + let p: Rc::>; + if self.free_timer_list.borrow().empty() { + p = self.free_timer_list.borrow().first_entry().upgrade().unwrap(); + if Rc::weak_count(&p.borrow().wp) > 0 { + p.borrow_mut().wp = Rc::new(p.borrow().holder.clone()); + } + } else { + p = Rc::new(RefCell::new(TimerList{ + holder: Default::default(), + wp: Default::default(), + timer_entry: Default::default(), + attach_entry: Default::default(), + timer_type: TimerType::Timeout, + expire_time: 0, + expires: 0, + cb: None, + })); + p.borrow_mut().holder = p.clone(); + p.borrow_mut().wp = Rc::new(p.borrow().holder.clone()); + p.borrow_mut().timer_entry = crate::ListHead::::new_node( + Rc::downgrade(&p.borrow().holder) + ); + p.borrow_mut().attach_entry = crate::ListHead::::new_head(); + } + return p; + } + + fn cascade(&mut self, idx: usize) -> usize { + let index = self.get_timer_index(idx); + let tv : &mut [TimerListListHeadRp]; + match idx { + 0 => { + tv = &mut self.tv2; + } + 1 => { + tv = &mut self.tv3; + } + 2 => { + tv = &mut self.tv4; + } + 3 => { + tv = &mut self.tv5; + } + _ => { + tv = &mut self.tv5; + } + } + if !tv[index].borrow().empty() { + let mut cascade_list = crate::ListHead::::new_head(); + tv[index].borrow_mut().replace_init(&mut cascade_list); + while !cascade_list.borrow().empty() { + let timer = &cascade_list.borrow().first_entry().upgrade().unwrap(); + timer.borrow_mut().timer_entry.borrow_mut().del_init(); + self.internal_add2(timer); + } + } + return index; + } + + fn get_timer_index(&self, index : usize) -> usize { + return ((self.timer_tick as usize) >> (TVR_BITS + index * TVN_BITS)) & TVN_MASK; + } + + pub fn update(&mut self) { + let tick = (self.get_tick_count)(); + while tick >= self.timer_tick { + let index = (self.timer_tick & (TVR_MASK as i64)) as usize; + if index == 0 && + self.cascade(0) == 0 && + self.cascade(1) == 0 && + self.cascade(2) == 0 { + self.cascade(3); + } + self.timer_tick += 1; + + self.work_list.borrow_mut().replace_init(&mut self.tv1[index]); + while !self.work_list.borrow().empty() { + let timer = &self.work_list.borrow().first_entry(); + self.running_timer = timer.clone(); + match &mut timer.upgrade().unwrap().borrow_mut().cb { + Some(v) => { + (*v)(TimerEvent::Exec, None); + } + None => { + } + } + match self.running_timer.upgrade() { + Some(v) => { + match v.borrow().timer_type { + TimerType::Timeout => { + self.internal_delete(Rc::downgrade(&v.borrow().wp), false); + } + TimerType::Interval => { + self.modify(Rc::downgrade(&v.borrow().wp), + v.borrow().expire_time); + } + } + } + None => { + } + } + } + } + self.running_timer = Weak::new(); + } + + fn internal_add(&mut self, + timer_type: TimerType, + expire_time: i32, + cb: TimerCb, + attacher: Option) -> XTimerWp { + let t = self.new_timer_list(); + t.borrow_mut().cb = Some(cb); + t.borrow_mut().timer_type = timer_type; + t.borrow_mut().expire_time = expire_time; + t.borrow_mut().expires = (self.get_tick_count)() + expire_time as i64; + match attacher { + Some(v) => { + v.borrow_mut().timers.borrow_mut().add_tail(&t.borrow_mut().attach_entry); + } + None => { + + } + } + self.internal_add2(&t); + return Rc::downgrade(&t.borrow().wp); + } + + fn internal_add2(&mut self, t: &Rc::>) { + let idx = t.borrow().expires - self.timer_tick; + let index; + let vec: &mut Rc::>>; + if idx < 0 { + index = self.timer_tick & (TVR_MASK as i64); + vec = &mut self.tv1[index as usize]; + } else if idx < TVR_SIZE as i64 { + index = t.borrow().expires & (TVR_MASK as i64); + vec = &mut self.tv1[index as usize]; + } else if idx < (1 << (TVR_BITS + TVN_BITS)) { + index = (t.borrow().expires >> TVR_BITS) & (TVN_MASK as i64); + vec = &mut self.tv2[index as usize]; + } else if idx < (1 << (TVR_BITS + 2 * TVN_BITS)) { + index = (t.borrow().expires >> (TVR_BITS + 1 * TVN_BITS)) & (TVN_MASK as i64); + vec = &mut self.tv3[index as usize]; + } else if idx < (1 << (TVR_BITS + 3 * TVN_BITS)) { + index = (t.borrow().expires >> (TVR_BITS + 2 * TVN_BITS)) & (TVN_MASK as i64); + vec = &mut self.tv4[index as usize]; + } else { + index = (t.borrow().expires >> (TVR_BITS + 3 * TVN_BITS)) & (TVN_MASK as i64); + vec = &mut self.tv5[index as usize]; + } + vec.borrow_mut().add_tail(&t.borrow_mut().timer_entry); + } + + fn internal_delete(&mut self, timer_wp: XTimerWp, is_destory: bool) { + match timer_wp.upgrade() { + Some(v) => { + if Weak::ptr_eq(&self.running_timer, &Rc::downgrade(&v)) { + self.running_timer = Weak::new(); + } + self.detach_timer(&*v); + match &mut v.borrow_mut().cb { + Some(cb) => { + if is_destory { + (*cb)(TimerEvent::Destory, None); + } else { + (*cb)(TimerEvent::Delete, None); + } + v.borrow_mut().cb = None; + } + None => { + } + } + if Rc::weak_count(&v.borrow().wp) > 0 { + v.borrow_mut().wp = Rc::new(v.borrow().holder.clone()); + } + self.free_timer_list.borrow_mut().add_tail(&v.borrow_mut().timer_entry); + self.free_timer_num += 1; + } + None => { + } + } + } + + pub fn set_timeout(&mut self, time: i32, cb: TimerCb) -> XTimerWp { + return self.internal_add(TimerType::Timeout, time, cb, None); + } + + pub fn set_timeout_ex + (&mut self, time: i32, cb: TimerCb, attacher: XTimerAttacherRp) -> XTimerWp { + return self.internal_add(TimerType::Timeout, time, cb, Some(attacher)); + } + + pub fn set_interval(&mut self, time: i32, cb: TimerCb) -> XTimerWp { + return self.internal_add(TimerType::Interval, time, cb, None); + } + + pub fn set_interval_ex + (&mut self, time: i32, cb: TimerCb, attacher: XTimerAttacherRp) -> XTimerWp { + return self.internal_add(TimerType::Interval, time, cb, Some(attacher)); + } + + pub fn fire_event(&mut self, + timer_wp: XTimerWp, + e: TimerEvent, + args: Option>>) { + match timer_wp.upgrade() { + Some(t) => { + match &mut t.borrow_mut().cb { + Some(cb) => { + (*cb)(e, args); + } + None => { + } + } + } + None => { + } + } + } + + pub fn modify(&mut self, timer_wp: XTimerWp, expire_time: i32) { + match timer_wp.upgrade() { + Some(_) => { + self.modify(timer_wp, expire_time); + } + None => { + } + } + } + + pub fn delete_current_timer(&mut self) { + match self.running_timer.upgrade() { + Some(v) => { + self.internal_delete(Rc::downgrade(&v.borrow().wp), false); + } + None => { + } + } + } + + pub fn is_running(&self) -> bool { + match self.running_timer.upgrade() { + Some(_) => { + return true; + } + None => { + return false; + } + } + } + + pub fn delete(&mut self, timer_wp: XTimerWp) { + match timer_wp.upgrade() { + Some(_) => { + self.internal_delete(timer_wp, false); + } + None => { + } + } + } + + pub fn get_remain_time(&mut self, timer_wp: XTimerWp) -> i64 { + match timer_wp.upgrade() { + Some(t) => { + let remain_time = t.borrow().expires - (self.get_tick_count)(); + return cmp::max(remain_time, 0); + } + None => { + return 0; + } + } + } + + pub fn get_idle_time(&self) -> i64 { + let mut idle_time = 0; + let start_idx = (self.timer_tick as usize) & TVR_MASK; + for i in start_idx..self.tv1.len() { + if !self.tv1[i].borrow().empty() { + break; + } + idle_time += 1; + } + return idle_time; + } + + fn gc_timer(&mut self, e: TimerEvent, _args: Option>>) { + match e { + TimerEvent::Exec => { + while self.free_timer_num > self.cache_timer_num && + !self.free_timer_list.borrow().empty() { + let timer = &self.free_timer_list.borrow().first_entry().upgrade().unwrap(); + timer.borrow_mut().timer_entry.borrow_mut().del_init(); + self.free_timer_num -= 1; + } + } + _ => { + + } + } + } + + fn detach_timer(&self, timer: &Rc::>) { + if !timer.borrow().timer_entry.borrow().empty() { + timer.borrow().timer_entry.borrow_mut().del_init() + } + } + +}