rust_rsm/rsm/
rsm_timer.rs1#![allow(non_camel_case_types)]
2#![allow(non_snake_case)]
3#![allow(non_upper_case_globals)]
4#![allow(dead_code)]
5
6use super::*;
14use crate::common::{self,errcode,tsidallocator::TsIdAllocator,tsmap::TsHashMap};
15use os_timer;
16const MAX_TIMER_COUNT:usize = 192*1024;
17const MAX_TIMER_PER_CAT:usize = 64*1024;
18const INVALID_TIMER_ID:rsm_timer_id_t = TsIdAllocator::INVALID_ID;
19
20const TIMER_CAT_10MS:u8=1;
21const TIMER_CAT_100MS:u8=2;
22const TIMER_CAT_1S:u8=3;
23
24#[derive(Clone,Default)]
25pub struct timer_stats_t {
26 total:usize,
27 timer_count_10ms:usize,
28 timer_count_100ms:usize,
29 timer_count_1s:usize,
30}
31
32struct timer_desc_t {
33 id:rsm_timer_id_t,
34 duration_msec:u64,
35 loop_count:u64,
36 timer_data:usize,
37 last_fired:u64,
38 expired_count:u64,
39 cid:rsm_component_t,
40}
41
42type timer_hash_map = TsHashMap<rsm_timer_id_t,timer_desc_t>;
43static mut gTimerIdAlloc:Option<TsIdAllocator>=None;
44static mut gTimerCatMap:[u8;MAX_TIMER_COUNT+1]=[0;MAX_TIMER_COUNT+1];
45static mut gTimer10ms:Option<timer_hash_map>=None;
46static mut gTimer100ms:Option<timer_hash_map>=None;
47static mut gTimer1s:Option<timer_hash_map>=None;
48
49pub(crate) fn init_timer() {
51 unsafe {
52 if gTimerIdAlloc.is_some() {
53 return
54 }
55 gTimerIdAlloc = Some(TsIdAllocator::new(1, MAX_TIMER_COUNT as i32));
56 gTimer10ms = Some(TsHashMap::new(MAX_TIMER_PER_CAT));
57 gTimer100ms = Some(TsHashMap::new(MAX_TIMER_PER_CAT));
58 gTimer1s = Some(TsHashMap::new(MAX_TIMER_PER_CAT));
59 }
60
61 println!("RSM Init Timer finished");
62}
63
64fn get_timer_cb_by_duration(dur_msec:u64)->Option<&'static mut timer_hash_map> {
65 if dur_msec<100 {
66 return unsafe {(&mut gTimer10ms).as_mut()}
67 } else if dur_msec<1000{
68 return unsafe {(&mut gTimer100ms).as_mut()}
69 }
70 return unsafe {(&mut gTimer1s).as_mut()}
71}
72
73fn get_timer_cb_by_cat(timer_cat:u8)->Option<&'static mut timer_hash_map> {
74 match timer_cat {
75 TIMER_CAT_10MS=> return unsafe {(&mut gTimer10ms).as_mut()},
76 TIMER_CAT_100MS=> return unsafe {(&mut gTimer100ms).as_mut()},
77 TIMER_CAT_1S=> return unsafe {(&mut gTimer1s).as_mut()},
78 _=>None,
79 }
80}
81
82fn get_timer_cat(dur_msec:u64)->u8 {
83 if dur_msec<100 {
84 return TIMER_CAT_10MS
85 } else if dur_msec<1000{
86 return TIMER_CAT_100MS
87 }
88 return TIMER_CAT_1S
89}
90
91fn set_timer_cat_map(id:rsm_timer_id_t,cat:u8)->errcode::RESULT {
92 if cat<TIMER_CAT_10MS || cat>TIMER_CAT_1S || id as usize>MAX_TIMER_COUNT{
93 return errcode::ERROR_INVALID_PARAM
94 }
95 unsafe {
96 gTimerCatMap[id as usize] = cat;
97 }
98
99 errcode::RESULT_SUCCESS
100}
101pub fn set_timer(dur_msec:u64,loop_count:u64,timer_data:usize)->Option<rsm_timer_id_t> {
103 let ida = match unsafe { &mut gTimerIdAlloc} {
104 None=>return None,
105 Some(a)=> a,
106 };
107 let id = ida.allocate_id();
108 if id==INVALID_TIMER_ID {
109 return None;
110 }
111 let caller = match rsm_sched::get_self_cid() {
112 None=>return None,
113 Some(c)=>c,
114 };
115 let timer = timer_desc_t {
116 id:id,
117 duration_msec:dur_msec,
118 loop_count:loop_count,
119 timer_data:timer_data,
120 last_fired:get_inner_time_stamp(),
121 cid:caller,
122 expired_count:0,
123 };
124
125 let timer_cat = get_timer_cat(dur_msec);
126 let timer_map = match get_timer_cb_by_cat(timer_cat) {
127 None=>return None,
128 Some(m)=>m,
129 };
130 if timer_map.insert(id,timer)!=errcode::RESULT_SUCCESS {
131 ida.release_id(id);
132 return None
133 }
134 set_timer_cat_map(id, timer_cat);
135 return Some(id)
136}
137
138pub fn kill_timer_by_id(timer_id:rsm_timer_id_t)->errcode::RESULT {
139 if timer_id as usize> MAX_TIMER_COUNT {
140 return errcode::ERROR_INVALID_PARAM
141 }
142
143 let cid=match rsm_sched::get_self_cid() {
144 None=>return errcode::ERROR_INVALID_STATE,
145 Some(c)=>c,
146 };
147 let cat = unsafe {gTimerCatMap[timer_id as usize]};
148 let pMap = match get_timer_cb_by_cat(cat) {
149 None=>return errcode::ERROR_NOT_FOUND,
150 Some(m)=>m
151 };
152
153 if let Some(timer) = pMap.get(&timer_id) {
154 if timer.cid !=cid {
155 return errcode::ERROR_INVALID_STATE;
156 }
157 } else {
158 return errcode::ERROR_NOT_FOUND
159 }
160 pMap.remove(&timer_id);
161
162 match unsafe { &mut gTimerIdAlloc} {
163 None=>(),
164 Some(a)=>{
165 a.release_id(timer_id);
166 },
167 }
168 errcode::RESULT_SUCCESS
169}
170
171pub(crate) fn start_timer_thread() {
173
174 init_timer();
175
176 std::thread::spawn(move || {
177 timer_loop()
178 });
179}
180static mut cur_time_stamp:u64=0;
181fn incr_inner_time_stamp() {
182 unsafe {
184 cur_time_stamp=common::get_now_usec64()/1000;
185 }
186}
187
188fn get_inner_time_stamp()->u64 {
189 unsafe {
190 return cur_time_stamp;
191 }
192}
193
194const TIMER_TASK_INNER:usize = 1;
195const TIMER_TASK_10MS:usize = 2;
196const TIMER_TASK_100MS:usize = 3;
197const TIMER_TASK_1S:usize = 4;
198fn timer_loop() {
199 os_timer::init_os_timer();
200 let _tm = match os_timer::os_timer_t::new(10,TIMER_TASK_10MS,scan_timer_call_back) {
201 None=> {
202 println!("set time failed");
203 return
204 },
205 Some(t)=>t,
206 };
207
208 loop {
209 std::thread::sleep(std::time::Duration::from_millis(1000));
210 }
211}
212
213fn send_timer_msg(cid:&rsm_component_t,tid:rsm_timer_id_t,timer_data:usize) {
215 let timer_msg = match rsm_message_t::new_timer_msg(tid, timer_data) {
216 None=>return,
217 Some(m)=>m,
218 };
219 rsm_sched::send_asyn_priority_msg(cid, timer_msg);
220}
221
222fn scan_timer_call_back(_timerId:i32,timer_data:usize) {
224 static mut count:u64=0;
225 match timer_data {
226 TIMER_TASK_10MS=> {
228 unsafe { count+=1;};
229 incr_inner_time_stamp();
230 scan_timer_10ms();
231 if unsafe { count % 10==0} {
232 scan_timer_100ms();
233 }
234 if unsafe { count % 100==0 } {
235 scan_timer_1s();
236 }
237
238 },
239 _=>(),
240 }
241}
242fn scan_timer_10ms() {
244 let tMap = match unsafe { &mut gTimer10ms} {
245 None=>return,
246 Some(m)=>m,
247 };
248 scan_timer_proc(tMap);
249}
250
251fn scan_timer_100ms() {
252 let tMap = match unsafe { &mut gTimer100ms} {
253 None=>return,
254 Some(m)=>m,
255 };
256 scan_timer_proc(tMap);
257}
258
259fn scan_timer_1s() {
260 let tMap = match unsafe { &mut gTimer1s} {
261 None=>return,
262 Some(m)=>m,
263 };
264 scan_timer_proc(tMap);
265}
266
267fn scan_timer_proc(timer_map:&mut timer_hash_map) {
268 let cur = get_inner_time_stamp();let mut to_delete=Vec::new();
270 for (id,t) in timer_map.iter_mut() {
271 if cur>=t.last_fired+t.duration_msec {
272 send_timer_msg(&t.cid, *id, t.timer_data);
273 t.last_fired=cur;
274 t.expired_count+=1;
275 if t.loop_count>0 && t.expired_count>=t.loop_count {
276 to_delete.push(t.id);
277 }
278
279 }
280 }
281 timer_map.end_iter();
282 for i in to_delete {
284 timer_map.remove(&i);
285 }
286}
287
288pub fn get_timer_stats()->timer_stats_t {
289 let mut stats = timer_stats_t::default();
290 unsafe {
291 stats.total = match &gTimerIdAlloc {
292 None=>0,
293 Some(ids)=>ids.used_count() as usize,
294 };
295
296 stats.timer_count_10ms = match &gTimer10ms {
297 None=>0,
298 Some(tm)=>tm.len(),
299 };
300
301 stats.timer_count_100ms = match &gTimer100ms {
302 None=>0,
303 Some(tm)=>tm.len(),
304 };
305 stats.timer_count_1s = match &gTimer1s {
306 None=>0,
307 Some(tm)=>tm.len(),
308 };
309 }
310
311
312 return stats
313}