1 use core::sync::atomic::{compiler_fence, AtomicBool, Ordering};
2 
3 use alloc::{
4     boxed::Box,
5     collections::LinkedList,
6     sync::{Arc, Weak},
7 };
8 
9 use crate::{
10     arch::{
11         asm::current::current_pcb,
12         interrupt::{cli, sti},
13         sched::sched,
14     },
15     exception::softirq::{softirq_vectors, SoftirqNumber, SoftirqVec},
16     include::bindings::bindings::{process_control_block, process_wakeup, pt_regs, PROC_RUNNING},
17     kdebug, kerror,
18     libs::spinlock::SpinLock,
19     syscall::SystemError,
20 };
21 
22 const MAX_TIMEOUT: i64 = i64::MAX;
23 const TIMER_RUN_CYCLE_THRESHOLD: usize = 20;
24 static mut TIMER_JIFFIES: u64 = 0;
25 
26 lazy_static! {
27     pub static ref TIMER_LIST: SpinLock<LinkedList<Arc<Timer>>> = SpinLock::new(LinkedList::new());
28 }
29 
30 /// 定时器要执行的函数的特征
31 pub trait TimerFunction: Send + Sync {
run(&mut self)32     fn run(&mut self);
33 }
34 
35 /// WakeUpHelper函数对应的结构体
36 pub struct WakeUpHelper {
37     pcb: &'static mut process_control_block,
38 }
39 
40 impl WakeUpHelper {
new(pcb: &'static mut process_control_block) -> Box<WakeUpHelper>41     pub fn new(pcb: &'static mut process_control_block) -> Box<WakeUpHelper> {
42         return Box::new(WakeUpHelper { pcb });
43     }
44 }
45 
46 impl TimerFunction for WakeUpHelper {
run(&mut self)47     fn run(&mut self) {
48         unsafe {
49             process_wakeup(self.pcb);
50         }
51     }
52 }
53 
54 pub struct Timer(SpinLock<InnerTimer>);
55 
56 impl Timer {
57     /// @brief 创建一个定时器(单位:ms)
58     ///
59     /// @param timer_func 定时器需要执行的函数对应的结构体
60     ///
61     /// @param expire_jiffies 定时器结束时刻
62     ///
63     /// @return 定时器结构体
new(timer_func: Box<dyn TimerFunction>, expire_jiffies: u64) -> Arc<Self>64     pub fn new(timer_func: Box<dyn TimerFunction>, expire_jiffies: u64) -> Arc<Self> {
65         let result: Arc<Timer> = Arc::new(Timer(SpinLock::new(InnerTimer {
66             expire_jiffies,
67             timer_func,
68             self_ref: Weak::default(),
69         })));
70 
71         result.0.lock().self_ref = Arc::downgrade(&result);
72 
73         return result;
74     }
75 
76     /// @brief 将定时器插入到定时器链表中
activate(&self)77     pub fn activate(&self) {
78         let inner_guard = self.0.lock();
79         let timer_list = &mut TIMER_LIST.lock();
80 
81         // 链表为空,则直接插入
82         if timer_list.is_empty() {
83             // FIXME push_timer
84 
85             timer_list.push_back(inner_guard.self_ref.upgrade().unwrap());
86 
87             drop(inner_guard);
88             drop(timer_list);
89             compiler_fence(Ordering::SeqCst);
90 
91             return;
92         }
93         let mut split_pos: usize = 0;
94         for (pos, elt) in timer_list.iter().enumerate() {
95             if elt.0.lock().expire_jiffies > inner_guard.expire_jiffies {
96                 split_pos = pos;
97                 break;
98             }
99         }
100         let mut temp_list: LinkedList<Arc<Timer>> = timer_list.split_off(split_pos);
101         timer_list.push_back(inner_guard.self_ref.upgrade().unwrap());
102         timer_list.append(&mut temp_list);
103         drop(inner_guard);
104         drop(timer_list);
105     }
106 
107     #[inline]
run(&self)108     fn run(&self) {
109         self.0.lock().timer_func.run();
110     }
111 }
112 
113 /// 定时器类型
114 pub struct InnerTimer {
115     /// 定时器结束时刻
116     pub expire_jiffies: u64,
117     /// 定时器需要执行的函数结构体
118     pub timer_func: Box<dyn TimerFunction>,
119     /// self_ref
120     self_ref: Weak<Timer>,
121 }
122 
123 #[derive(Debug)]
124 pub struct DoTimerSoftirq {
125     running: AtomicBool,
126 }
127 
128 impl DoTimerSoftirq {
new() -> Self129     pub fn new() -> Self {
130         return DoTimerSoftirq {
131             running: AtomicBool::new(false),
132         };
133     }
134 
set_run(&self) -> bool135     fn set_run(&self) -> bool {
136         let x = self
137             .running
138             .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed);
139         if x.is_ok() {
140             return true;
141         } else {
142             return false;
143         }
144     }
145 
clear_run(&self)146     fn clear_run(&self) {
147         self.running.store(false, Ordering::Release);
148     }
149 }
150 impl SoftirqVec for DoTimerSoftirq {
run(&self)151     fn run(&self) {
152         if self.set_run() == false {
153             return;
154         }
155         // 最多只处理TIMER_RUN_CYCLE_THRESHOLD个计时器
156         for _ in 0..TIMER_RUN_CYCLE_THRESHOLD {
157             // kdebug!("DoTimerSoftirq run");
158             let timer_list = TIMER_LIST.try_lock();
159             if timer_list.is_err() {
160                 continue;
161             }
162             let mut timer_list = timer_list.unwrap();
163 
164             if timer_list.is_empty() {
165                 break;
166             }
167 
168             let timer_list_front = timer_list.pop_front().unwrap();
169             // kdebug!("to lock timer_list_front");
170             let mut timer_list_front_guard = None;
171             for _ in 0..10 {
172                 let x = timer_list_front.0.try_lock();
173                 if x.is_err() {
174                     continue;
175                 }
176                 timer_list_front_guard = Some(x.unwrap());
177             }
178             if timer_list_front_guard.is_none() {
179                 continue;
180             }
181             let timer_list_front_guard = timer_list_front_guard.unwrap();
182             if timer_list_front_guard.expire_jiffies > unsafe { TIMER_JIFFIES as u64 } {
183                 drop(timer_list_front_guard);
184                 timer_list.push_front(timer_list_front);
185                 break;
186             }
187             drop(timer_list_front_guard);
188             drop(timer_list);
189             timer_list_front.run();
190         }
191 
192         self.clear_run();
193     }
194 }
195 
196 /// @brief 初始化timer模块
timer_init()197 pub fn timer_init() {
198     // FIXME 调用register_trap
199     let do_timer_softirq = Arc::new(DoTimerSoftirq::new());
200     softirq_vectors()
201         .register_softirq(SoftirqNumber::TIMER, do_timer_softirq)
202         .expect("Failed to register timer softirq");
203     kdebug!("timer initiated successfully");
204 }
205 
206 /// 计算接下来n毫秒对应的定时器时间片
next_n_ms_timer_jiffies(expire_ms: u64) -> u64207 pub fn next_n_ms_timer_jiffies(expire_ms: u64) -> u64 {
208     return unsafe { TIMER_JIFFIES as u64 } + 1000 * (expire_ms);
209 }
210 /// 计算接下来n微秒对应的定时器时间片
next_n_us_timer_jiffies(expire_us: u64) -> u64211 pub fn next_n_us_timer_jiffies(expire_us: u64) -> u64 {
212     return unsafe { TIMER_JIFFIES as u64 } + (expire_us);
213 }
214 
215 /// @brief 让pcb休眠timeout个jiffies
216 ///
217 /// @param timeout 需要休眠的时间(单位:jiffies)
218 ///
219 /// @return Ok(i64) 剩余需要休眠的时间(单位:jiffies)
220 ///
221 /// @return Err(SystemError) 错误码
schedule_timeout(mut timeout: i64) -> Result<i64, SystemError>222 pub fn schedule_timeout(mut timeout: i64) -> Result<i64, SystemError> {
223     // kdebug!("schedule_timeout");
224     if timeout == MAX_TIMEOUT {
225         sched();
226         return Ok(MAX_TIMEOUT);
227     } else if timeout < 0 {
228         kerror!("timeout can't less than 0");
229         return Err(SystemError::EINVAL);
230     } else {
231         // 禁用中断,防止在这段期间发生调度,造成死锁
232         cli();
233         timeout += unsafe { TIMER_JIFFIES } as i64;
234         let timer = Timer::new(WakeUpHelper::new(current_pcb()), timeout as u64);
235         timer.activate();
236         current_pcb().state &= (!PROC_RUNNING) as u64;
237         sti();
238 
239         sched();
240         let time_remaining: i64 = timeout - unsafe { TIMER_JIFFIES } as i64;
241         if time_remaining >= 0 {
242             // 被提前唤醒,返回剩余时间
243             return Ok(time_remaining);
244         } else {
245             return Ok(0);
246         }
247     }
248 }
249 
timer_get_first_expire() -> Result<u64, SystemError>250 pub fn timer_get_first_expire() -> Result<u64, SystemError> {
251     // FIXME
252     // kdebug!("rs_timer_get_first_expire,timer_jif = {:?}", TIMER_JIFFIES);
253     for _ in 0..10 {
254         match TIMER_LIST.try_lock() {
255             Ok(timer_list) => {
256                 // kdebug!("rs_timer_get_first_expire TIMER_LIST lock successfully");
257                 if timer_list.is_empty() {
258                     // kdebug!("timer_list is empty");
259                     return Ok(0);
260                 } else {
261                     // kdebug!("timer_list not empty");
262                     return Ok(timer_list.front().unwrap().0.lock().expire_jiffies);
263                 }
264             }
265             // 加锁失败返回啥??
266             Err(_) => continue,
267         }
268     }
269     return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
270 }
271 
update_timer_jiffies(add_jiffies: u64) -> u64272 pub fn update_timer_jiffies(add_jiffies: u64) -> u64 {
273     unsafe { TIMER_JIFFIES += add_jiffies };
274     return unsafe { TIMER_JIFFIES };
275 }
clock() -> u64276 pub fn clock() -> u64 {
277     return unsafe { TIMER_JIFFIES };
278 }
279 // ====== 重构完成后请删掉extern C ======
280 #[no_mangle]
rs_clock() -> u64281 pub extern "C" fn rs_clock() -> u64 {
282     clock()
283 }
284 #[no_mangle]
sys_clock(_regs: *const pt_regs) -> u64285 pub extern "C" fn sys_clock(_regs: *const pt_regs) -> u64 {
286     clock()
287 }
288 
289 // ====== 以下为给C提供的接口 ======
290 #[no_mangle]
rs_schedule_timeout(timeout: i64) -> i64291 pub extern "C" fn rs_schedule_timeout(timeout: i64) -> i64 {
292     match schedule_timeout(timeout) {
293         Ok(v) => {
294             return v;
295         }
296         Err(e) => {
297             kdebug!("rs_schedule_timeout run failed");
298             return e.to_posix_errno() as i64;
299         }
300     }
301 }
302 
303 #[no_mangle]
rs_timer_init()304 pub extern "C" fn rs_timer_init() {
305     timer_init();
306 }
307 
308 #[no_mangle]
rs_timer_next_n_ms_jiffies(expire_ms: u64) -> u64309 pub extern "C" fn rs_timer_next_n_ms_jiffies(expire_ms: u64) -> u64 {
310     return next_n_ms_timer_jiffies(expire_ms);
311 }
312 
313 #[no_mangle]
rs_timer_next_n_us_jiffies(expire_us: u64) -> u64314 pub extern "C" fn rs_timer_next_n_us_jiffies(expire_us: u64) -> u64 {
315     return next_n_us_timer_jiffies(expire_us);
316 }
317 
318 #[no_mangle]
rs_timer_get_first_expire() -> i64319 pub extern "C" fn rs_timer_get_first_expire() -> i64 {
320     match timer_get_first_expire() {
321         Ok(v) => return v as i64,
322         Err(_) => return 0,
323     }
324 }
325 
326 #[no_mangle]
rs_update_timer_jiffies(add_jiffies: u64) -> u64327 pub extern "C" fn rs_update_timer_jiffies(add_jiffies: u64) -> u64 {
328     return update_timer_jiffies(add_jiffies);
329 }
330