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