use std::rc::{Rc, Weak}; use std::cell::RefCell; use std::any::Any; use std::cmp; use std::time::{Instant}; use r9_macro::SharedFromSelf; use r9_macro_derive::SharedFromSelf; 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, } #[derive(Clone)] enum TimerType { Timeout, Interval } impl Default for TimerType { fn default() -> Self { return TimerType::Timeout; } } #[derive(Default)] pub struct TimerList { holder: Option, wp: Option>, 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: Option i64>>, cache_timer_num: i32, work_list: TimerListListHeadRp, tv1: Vec, tv2: Vec, tv3: Vec, tv4: Vec, tv5: Vec, _self_wp: Weak::>, } impl XTimer { pub fn new() -> Rc::> { let this = Rc::new(RefCell::new(XTimer{ free_timer_num: 0, free_timer_list: Default::default(), running_timer: Default::default(), timer_tick: Default::default(), get_tick_count: Default::default(), cache_timer_num: 0, work_list: Default::default(), tv1: Vec::with_capacity(TVR_SIZE), tv2: Vec::with_capacity(TVN_SIZE), tv3: Vec::with_capacity(TVN_SIZE), tv4: Vec::with_capacity(TVN_SIZE), tv5: Vec::with_capacity(TVN_SIZE), _self_wp: Default::default(), })); this.borrow_mut()._self_wp = Rc::downgrade(&this); return this; } pub fn init(&mut self, get_tick_count: Box i64>, gctime: i32, cache_timer_num: i32) { self.get_tick_count = Some(get_tick_count); self.cache_timer_num = cache_timer_num; self.free_timer_num = 0; self.free_timer_list = crate::ListHead::::new_head(); self.work_list = crate::ListHead::::new_head(); for _ in 0..TVR_SIZE { self.tv1.push(crate::ListHead::::new_head()); } for _ in 0..TVN_SIZE { self.tv2.push(crate::ListHead::::new_head()); self.tv3.push(crate::ListHead::::new_head()); self.tv4.push(crate::ListHead::::new_head()); self.tv5.push(crate::ListHead::::new_head()); } match &self.get_tick_count { Some(v) => { self.timer_tick = (*v)(); } None => { } } { 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); } 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.clone().unwrap()) > 0 { p.borrow_mut().wp = Some(Rc::new(p.borrow().holder.clone().unwrap())); } } 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 = Some(p.clone()); { let z = Some(Rc::new(p.borrow().holder.clone().unwrap())); p.borrow_mut().wp = z; } p.borrow_mut().timer_entry = crate::ListHead::::new_node( Rc::downgrade(&p) ); p.borrow_mut().attach_entry = crate::ListHead::::new_head(); } return p; } fn cascade(&self, idx: usize) -> usize { let index = self.get_timer_index(idx); let tv : &[TimerListListHeadRp]; match idx { 0 => { tv = &self.tv2; } 1 => { tv = &self.tv3; } 2 => { tv = &self.tv4; } 3 => { tv = &self.tv5; } _ => { tv = &self.tv5; } } if !tv[index].borrow().empty() { let cascade_list = crate::ListHead::::new_head(); crate::ListHead::::replace_init (&tv[index], &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; } fn fetch_work_list(&mut self, tick: i64) -> bool { if 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; crate::ListHead::::replace_init (&self.tv1[index], &self.work_list); return true; } else { return false; } } pub fn update(this: &Rc::>) { let tick = (*this.borrow().get_tick_count.as_ref().unwrap())(); let work_list = this.borrow().work_list.clone(); while this.borrow_mut().fetch_work_list(tick) { while !work_list.borrow().empty() { { let timer = &work_list.borrow().first_entry(); this.borrow_mut().running_timer = timer.clone(); match &mut timer.upgrade().unwrap().borrow_mut().cb { Some(v) => { (*v)(TimerEvent::Exec, None); } None => { } } } { let running_timer = this.borrow().running_timer.clone(); match running_timer.upgrade() { Some(v) => { let timer_wp = Rc::downgrade(&v.borrow().wp.as_ref().unwrap()); let timer_type = v.borrow().timer_type.clone(); let expire_time = v.borrow().expire_time; match timer_type { TimerType::Timeout => { this.borrow_mut().internal_delete (timer_wp, false); } TimerType::Interval => { this.borrow_mut().internal_modify( timer_wp, expire_time ); } } } None => { } } } } } this.borrow_mut().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; match &self.get_tick_count { Some(v) => { t.borrow_mut().expires = (*v)() + expire_time as i64; } None => { } } match attacher { Some(v) => { crate::ListHead::::add_tail (&v.borrow().timers, &t.borrow_mut().attach_entry); } None => { } } self.internal_add2(&t); return Rc::downgrade(&t.borrow().wp.clone().unwrap()); } fn internal_add2(&self, t: &Rc::>) { let idx = t.borrow().expires - self.timer_tick; let index; let vec: &Rc::>>; if idx < 0 { index = self.timer_tick & (TVR_MASK as i64); vec = &self.tv1[index as usize]; } else if idx < TVR_SIZE as i64 { index = t.borrow().expires & (TVR_MASK as i64); vec = &self.tv1[index as usize]; } else if idx < (1 << (TVR_BITS + TVN_BITS)) { index = (t.borrow().expires >> TVR_BITS) & (TVN_MASK as i64); vec = &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 = &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 = &self.tv4[index as usize]; } else { index = (t.borrow().expires >> (TVR_BITS + 3 * TVN_BITS)) & (TVN_MASK as i64); vec = &self.tv5[index as usize]; } crate::ListHead::::add_tail(&vec, &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.clone().unwrap()) > 0 { v.borrow_mut().wp = Some(Rc::new(v.borrow().holder.clone().unwrap())); } crate::ListHead::::add_tail (&self.free_timer_list, &v.borrow_mut().attach_entry); self.free_timer_num += 1; } None => { } } } fn internal_modify(&self, timer_wp: XTimerWp, expire_time: i32) { self.detach_timer(&timer_wp.upgrade().unwrap()); let timer = timer_wp.clone().upgrade().unwrap().clone(); timer.borrow_mut().expire_time = expire_time; timer.borrow_mut().expires = (*self.get_tick_count.as_ref().unwrap())() + expire_time as i64; self.internal_add2(&timer); } 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(_) => { } None => { } } self.internal_modify(timer_wp, expire_time); } pub fn delete_current_timer(&mut self) { match self.running_timer.upgrade() { Some(v) => { self.internal_delete(Rc::downgrade(&v.borrow().wp.clone().unwrap()), 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) => { match &self.get_tick_count { Some(v) => { let remain_time = t.borrow().expires - (*v)(); return cmp::max(remain_time, 0); } None => { return 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>>) { let now = Instant::now(); //println!("now: {:?}", now); 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() } } }