xref: /DragonOS/kernel/src/time/timer.rs (revision 1f4877a4c512eb5ad232436128a0c52287b39aaa)
1 use core::{
2     fmt::Debug,
3     intrinsics::unlikely,
4     sync::atomic::{compiler_fence, AtomicBool, AtomicU64, Ordering},
5     time::Duration,
6 };
7 
8 use alloc::{
9     boxed::Box,
10     sync::{Arc, Weak},
11     vec::Vec,
12 };
13 use system_error::SystemError;
14 
15 use crate::{
16     arch::CurrentIrqArch,
17     exception::{
18         softirq::{softirq_vectors, SoftirqNumber, SoftirqVec},
19         InterruptArch,
20     },
21     kerror, kinfo,
22     libs::spinlock::{SpinLock, SpinLockGuard},
23     process::{ProcessControlBlock, ProcessManager},
24     sched::{schedule, SchedMode},
25 };
26 
27 use super::{jiffies::NSEC_PER_JIFFY, timekeeping::update_wall_time};
28 
29 const MAX_TIMEOUT: i64 = i64::MAX;
30 const TIMER_RUN_CYCLE_THRESHOLD: usize = 20;
31 static TIMER_JIFFIES: AtomicU64 = AtomicU64::new(0);
32 
33 lazy_static! {
34     pub static ref TIMER_LIST: SpinLock<Vec<(u64, Arc<Timer>)>> = SpinLock::new(Vec::new());
35 }
36 
37 /// 定时器要执行的函数的特征
38 pub trait TimerFunction: Send + Sync + Debug {
39     fn run(&mut self) -> Result<(), SystemError>;
40 }
41 // # Jiffies结构体(注意这是一段时间的jiffies数而不是某一时刻的定时器时间片)
42 
43 int_like!(Jiffies, u64);
44 
45 impl Jiffies {
46     /// ## 返回接下来的n_jiffies对应的定时器时间片
47     pub fn timer_jiffies(&self) -> u64 {
48         let result = TIMER_JIFFIES.load(Ordering::SeqCst) + self.data();
49         result
50     }
51 }
52 
53 impl From<Jiffies> for Duration {
54     /// # Jiffies转Duration
55     ///
56     /// ## 参数
57     ///
58     /// jiffies: 一段时间的jiffies数
59     ///
60     /// ### 返回值
61     ///
62     /// Duration: 这段时间的Duration形式
63     fn from(jiffies: Jiffies) -> Self {
64         let ms = jiffies.data() / 1_000_000 * NSEC_PER_JIFFY as u64;
65         let result = Duration::from_millis(ms);
66         result
67     }
68 }
69 
70 impl From<Duration> for Jiffies {
71     /// # Duration 转 Jiffies
72     ///
73     /// ## 参数
74     ///
75     /// ms: 表示一段时间的Duration类型
76     ///
77     /// ### 返回值
78     ///
79     /// Jiffies结构体: 这段时间的Jiffies数
80     fn from(ms: Duration) -> Self {
81         let jiffies = ms.as_millis() as u64 * 1_000_000 / NSEC_PER_JIFFY as u64;
82         let result = Jiffies::new(jiffies);
83         result
84     }
85 }
86 
87 #[derive(Debug)]
88 /// WakeUpHelper函数对应的结构体
89 pub struct WakeUpHelper {
90     pcb: Arc<ProcessControlBlock>,
91 }
92 
93 impl WakeUpHelper {
94     pub fn new(pcb: Arc<ProcessControlBlock>) -> Box<WakeUpHelper> {
95         return Box::new(WakeUpHelper { pcb });
96     }
97 }
98 
99 impl TimerFunction for WakeUpHelper {
100     fn run(&mut self) -> Result<(), SystemError> {
101         ProcessManager::wakeup(&self.pcb).ok();
102         return Ok(());
103     }
104 }
105 
106 #[derive(Debug)]
107 pub struct Timer {
108     inner: SpinLock<InnerTimer>,
109 }
110 
111 impl Timer {
112     /// @brief 创建一个定时器(单位:ms)
113     ///
114     /// @param timer_func 定时器需要执行的函数对应的结构体
115     ///
116     /// @param expire_jiffies 定时器结束时刻
117     ///
118     /// @return 定时器结构体
119     pub fn new(timer_func: Box<dyn TimerFunction>, expire_jiffies: u64) -> Arc<Self> {
120         let result: Arc<Timer> = Arc::new(Timer {
121             inner: SpinLock::new(InnerTimer {
122                 expire_jiffies,
123                 timer_func: Some(timer_func),
124                 self_ref: Weak::default(),
125                 triggered: false,
126             }),
127         });
128 
129         result.inner.lock().self_ref = Arc::downgrade(&result);
130 
131         return result;
132     }
133 
134     pub fn inner(&self) -> SpinLockGuard<InnerTimer> {
135         return self.inner.lock_irqsave();
136     }
137 
138     /// @brief 将定时器插入到定时器链表中
139     pub fn activate(&self) {
140         let mut timer_list = TIMER_LIST.lock_irqsave();
141         let inner_guard = self.inner();
142 
143         // 链表为空,则直接插入
144         if timer_list.is_empty() {
145             // FIXME push_timer
146             timer_list.push((
147                 inner_guard.expire_jiffies,
148                 inner_guard.self_ref.upgrade().unwrap(),
149             ));
150 
151             drop(inner_guard);
152             drop(timer_list);
153             compiler_fence(Ordering::SeqCst);
154 
155             return;
156         }
157         let expire_jiffies = inner_guard.expire_jiffies;
158         let self_arc = inner_guard.self_ref.upgrade().unwrap();
159         drop(inner_guard);
160         let mut split_pos: usize = 0;
161         for (pos, elt) in timer_list.iter().enumerate() {
162             if Arc::ptr_eq(&self_arc, &elt.1) {
163                 kwarn!("Timer already in list");
164             }
165             if elt.0 > expire_jiffies {
166                 split_pos = pos;
167                 break;
168             }
169         }
170         timer_list.insert(split_pos, (expire_jiffies, self_arc));
171 
172         drop(timer_list);
173     }
174 
175     #[inline]
176     fn run(&self) {
177         let mut timer = self.inner();
178         timer.triggered = true;
179         let func = timer.timer_func.take();
180         drop(timer);
181         let r = func.map(|mut f| f.run()).unwrap_or(Ok(()));
182         if unlikely(r.is_err()) {
183             kerror!(
184                 "Failed to run timer function: {self:?} {:?}",
185                 r.as_ref().err().unwrap()
186             );
187         }
188     }
189 
190     /// ## 判断定时器是否已经触发
191     pub fn timeout(&self) -> bool {
192         self.inner().triggered
193     }
194 
195     /// ## 取消定时器任务
196     pub fn cancel(&self) -> bool {
197         let this_arc = self.inner().self_ref.upgrade().unwrap();
198         TIMER_LIST
199             .lock_irqsave()
200             .extract_if(|x| Arc::ptr_eq(&this_arc, &x.1))
201             .for_each(drop);
202         true
203     }
204 }
205 
206 /// 定时器类型
207 #[derive(Debug)]
208 pub struct InnerTimer {
209     /// 定时器结束时刻
210     pub expire_jiffies: u64,
211     /// 定时器需要执行的函数结构体
212     pub timer_func: Option<Box<dyn TimerFunction>>,
213     /// self_ref
214     self_ref: Weak<Timer>,
215     /// 判断该计时器是否触发
216     triggered: bool,
217 }
218 
219 #[derive(Debug)]
220 pub struct DoTimerSoftirq {
221     running: AtomicBool,
222 }
223 
224 impl DoTimerSoftirq {
225     pub fn new() -> Self {
226         return DoTimerSoftirq {
227             running: AtomicBool::new(false),
228         };
229     }
230 
231     fn set_run(&self) -> bool {
232         let x = self
233             .running
234             .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed);
235         return x.is_ok();
236     }
237 
238     fn clear_run(&self) {
239         self.running.store(false, Ordering::Release);
240     }
241 }
242 impl SoftirqVec for DoTimerSoftirq {
243     fn run(&self) {
244         if !self.set_run() {
245             return;
246         }
247         // 最多只处理TIMER_RUN_CYCLE_THRESHOLD个计时器
248         for _ in 0..TIMER_RUN_CYCLE_THRESHOLD {
249             // kdebug!("DoTimerSoftirq run");
250             let timer_list = TIMER_LIST.try_lock_irqsave();
251             if timer_list.is_err() {
252                 continue;
253             }
254             let mut timer_list = timer_list.unwrap();
255 
256             if timer_list.is_empty() {
257                 break;
258             }
259 
260             let (front_jiffies, timer_list_front) = timer_list.first().unwrap().clone();
261             // kdebug!("to lock timer_list_front");
262 
263             if front_jiffies >= TIMER_JIFFIES.load(Ordering::SeqCst) {
264                 break;
265             }
266             timer_list.remove(0);
267             drop(timer_list);
268             timer_list_front.run();
269         }
270 
271         self.clear_run();
272     }
273 }
274 
275 /// 初始化系统定时器
276 #[inline(never)]
277 pub fn timer_init() {
278     // FIXME 调用register_trap
279     let do_timer_softirq = Arc::new(DoTimerSoftirq::new());
280     softirq_vectors()
281         .register_softirq(SoftirqNumber::TIMER, do_timer_softirq)
282         .expect("Failed to register timer softirq");
283     kinfo!("timer initialized successfully");
284 }
285 
286 /// 计算接下来n毫秒对应的定时器时间片
287 pub fn next_n_ms_timer_jiffies(expire_ms: u64) -> u64 {
288     return TIMER_JIFFIES.load(Ordering::SeqCst) + expire_ms * 1000000 / NSEC_PER_JIFFY as u64;
289 }
290 /// 计算接下来n微秒对应的定时器时间片
291 pub fn next_n_us_timer_jiffies(expire_us: u64) -> u64 {
292     return TIMER_JIFFIES.load(Ordering::SeqCst) + expire_us * 1000 / NSEC_PER_JIFFY as u64;
293 }
294 
295 /// @brief 让pcb休眠timeout个jiffies
296 ///
297 /// @param timeout 需要休眠的时间(单位:jiffies)
298 ///
299 /// @return Ok(i64) 剩余需要休眠的时间(单位:jiffies)
300 ///
301 /// @return Err(SystemError) 错误码
302 pub fn schedule_timeout(mut timeout: i64) -> Result<i64, SystemError> {
303     // kdebug!("schedule_timeout");
304     if timeout == MAX_TIMEOUT {
305         let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
306         ProcessManager::mark_sleep(true).ok();
307         drop(irq_guard);
308         schedule(SchedMode::SM_NONE);
309         return Ok(MAX_TIMEOUT);
310     } else if timeout < 0 {
311         kerror!("timeout can't less than 0");
312         return Err(SystemError::EINVAL);
313     } else {
314         // 禁用中断,防止在这段期间发生调度,造成死锁
315         let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
316 
317         timeout += TIMER_JIFFIES.load(Ordering::SeqCst) as i64;
318         let timer = Timer::new(
319             WakeUpHelper::new(ProcessManager::current_pcb()),
320             timeout as u64,
321         );
322         ProcessManager::mark_sleep(true).ok();
323         timer.activate();
324 
325         drop(irq_guard);
326 
327         schedule(SchedMode::SM_NONE);
328         let time_remaining: i64 = timeout - TIMER_JIFFIES.load(Ordering::SeqCst) as i64;
329         if time_remaining >= 0 {
330             // 被提前唤醒,返回剩余时间
331             return Ok(time_remaining);
332         } else {
333             return Ok(0);
334         }
335     }
336 }
337 
338 pub fn timer_get_first_expire() -> Result<u64, SystemError> {
339     // FIXME
340     // kdebug!("rs_timer_get_first_expire,timer_jif = {:?}", TIMER_JIFFIES);
341     for _ in 0..10 {
342         match TIMER_LIST.try_lock_irqsave() {
343             Ok(timer_list) => {
344                 // kdebug!("rs_timer_get_first_expire TIMER_LIST lock successfully");
345                 if timer_list.is_empty() {
346                     // kdebug!("timer_list is empty");
347                     return Ok(0);
348                 } else {
349                     // kdebug!("timer_list not empty");
350                     return Ok(timer_list.first().unwrap().0);
351                 }
352             }
353             // 加锁失败返回啥??
354             Err(_) => continue,
355         }
356     }
357     return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
358 }
359 
360 /// 检查是否需要触发定时器软中断,如果需要则触发
361 pub fn try_raise_timer_softirq() {
362     if let Ok(first_expire) = timer_get_first_expire() {
363         if first_expire <= clock() {
364             softirq_vectors().raise_softirq(SoftirqNumber::TIMER);
365         }
366     }
367 }
368 
369 /// 更新系统时间片
370 pub fn update_timer_jiffies(add_jiffies: u64, time_us: i64) -> u64 {
371     let prev = TIMER_JIFFIES.fetch_add(add_jiffies, Ordering::SeqCst);
372     compiler_fence(Ordering::SeqCst);
373     update_wall_time(time_us);
374 
375     compiler_fence(Ordering::SeqCst);
376     return prev + add_jiffies;
377 }
378 
379 pub fn clock() -> u64 {
380     return TIMER_JIFFIES.load(Ordering::SeqCst);
381 }
382 
383 // ====== 以下为给C提供的接口 ======
384 
385 #[no_mangle]
386 pub extern "C" fn rs_timer_init() {
387     timer_init();
388 }
389