xref: /DragonOS/kernel/src/time/timer.rs (revision 8cb2e9b344230227fe5f3ab3ebeb2522f1c5e289)
136fd0130Shoumkh use core::{
236fd0130Shoumkh     fmt::Debug,
336fd0130Shoumkh     intrinsics::unlikely,
436fd0130Shoumkh     sync::atomic::{compiler_fence, AtomicBool, AtomicU64, Ordering},
536fd0130Shoumkh };
6bacd691cSlogin 
7bacd691cSlogin use alloc::{
8bacd691cSlogin     boxed::Box,
9bacd691cSlogin     collections::LinkedList,
10bacd691cSlogin     sync::{Arc, Weak},
11bacd691cSlogin };
1291e9d4abSLoGin use system_error::SystemError;
13bacd691cSlogin 
14bacd691cSlogin use crate::{
151496ba7bSLoGin     arch::{sched::sched, CurrentIrqArch},
1636fd0130Shoumkh     exception::{
1736fd0130Shoumkh         softirq::{softirq_vectors, SoftirqNumber, SoftirqVec},
1836fd0130Shoumkh         InterruptArch,
19bacd691cSlogin     },
20be8cdf4bSLoGin     kerror, kinfo,
210d6cf65aSLoGin     libs::spinlock::{SpinLock, SpinLockGuard},
221496ba7bSLoGin     process::{ProcessControlBlock, ProcessManager},
23bacd691cSlogin };
24bacd691cSlogin 
2536fd0130Shoumkh use super::timekeeping::update_wall_time;
2636fd0130Shoumkh 
27bacd691cSlogin const MAX_TIMEOUT: i64 = i64::MAX;
28bacd691cSlogin const TIMER_RUN_CYCLE_THRESHOLD: usize = 20;
2936fd0130Shoumkh static TIMER_JIFFIES: AtomicU64 = AtomicU64::new(0);
30bacd691cSlogin 
31bacd691cSlogin lazy_static! {
32bacd691cSlogin     pub static ref TIMER_LIST: SpinLock<LinkedList<Arc<Timer>>> = SpinLock::new(LinkedList::new());
33bacd691cSlogin }
34bacd691cSlogin 
35bacd691cSlogin /// 定时器要执行的函数的特征
3636fd0130Shoumkh pub trait TimerFunction: Send + Sync + Debug {
3736fd0130Shoumkh     fn run(&mut self) -> Result<(), SystemError>;
38bacd691cSlogin }
39bacd691cSlogin 
4036fd0130Shoumkh #[derive(Debug)]
41bacd691cSlogin /// WakeUpHelper函数对应的结构体
42bacd691cSlogin pub struct WakeUpHelper {
431496ba7bSLoGin     pcb: Arc<ProcessControlBlock>,
44bacd691cSlogin }
45bacd691cSlogin 
46bacd691cSlogin impl WakeUpHelper {
471496ba7bSLoGin     pub fn new(pcb: Arc<ProcessControlBlock>) -> Box<WakeUpHelper> {
48bacd691cSlogin         return Box::new(WakeUpHelper { pcb });
49bacd691cSlogin     }
50bacd691cSlogin }
51bacd691cSlogin 
52bacd691cSlogin impl TimerFunction for WakeUpHelper {
5336fd0130Shoumkh     fn run(&mut self) -> Result<(), SystemError> {
541496ba7bSLoGin         ProcessManager::wakeup(&self.pcb).ok();
5536fd0130Shoumkh         return Ok(());
56bacd691cSlogin     }
57bacd691cSlogin }
58bacd691cSlogin 
5936fd0130Shoumkh #[derive(Debug)]
600d6cf65aSLoGin pub struct Timer {
610d6cf65aSLoGin     inner: SpinLock<InnerTimer>,
620d6cf65aSLoGin }
63bacd691cSlogin 
64bacd691cSlogin impl Timer {
65bacd691cSlogin     /// @brief 创建一个定时器(单位:ms)
66bacd691cSlogin     ///
67bacd691cSlogin     /// @param timer_func 定时器需要执行的函数对应的结构体
68bacd691cSlogin     ///
69bacd691cSlogin     /// @param expire_jiffies 定时器结束时刻
70bacd691cSlogin     ///
71bacd691cSlogin     /// @return 定时器结构体
72bacd691cSlogin     pub fn new(timer_func: Box<dyn TimerFunction>, expire_jiffies: u64) -> Arc<Self> {
730d6cf65aSLoGin         let result: Arc<Timer> = Arc::new(Timer {
740d6cf65aSLoGin             inner: SpinLock::new(InnerTimer {
75bacd691cSlogin                 expire_jiffies,
760d6cf65aSLoGin                 timer_func: Some(timer_func),
77bacd691cSlogin                 self_ref: Weak::default(),
78971462beSGnoCiYeH                 triggered: false,
790d6cf65aSLoGin             }),
800d6cf65aSLoGin         });
81bacd691cSlogin 
820d6cf65aSLoGin         result.inner.lock().self_ref = Arc::downgrade(&result);
83bacd691cSlogin 
84bacd691cSlogin         return result;
85bacd691cSlogin     }
86bacd691cSlogin 
870d6cf65aSLoGin     pub fn inner(&self) -> SpinLockGuard<InnerTimer> {
880d6cf65aSLoGin         return self.inner.lock_irqsave();
890d6cf65aSLoGin     }
900d6cf65aSLoGin 
91bacd691cSlogin     /// @brief 将定时器插入到定时器链表中
92bacd691cSlogin     pub fn activate(&self) {
930d6cf65aSLoGin         let mut timer_list = TIMER_LIST.lock_irqsave();
940d6cf65aSLoGin         let inner_guard = self.inner();
95cde5492fSlogin 
96bacd691cSlogin         // 链表为空,则直接插入
97bacd691cSlogin         if timer_list.is_empty() {
98bacd691cSlogin             // FIXME push_timer
99cde5492fSlogin 
100bacd691cSlogin             timer_list.push_back(inner_guard.self_ref.upgrade().unwrap());
101cde5492fSlogin 
102cde5492fSlogin             drop(inner_guard);
103cde5492fSlogin             drop(timer_list);
104cde5492fSlogin             compiler_fence(Ordering::SeqCst);
105cde5492fSlogin 
106bacd691cSlogin             return;
107bacd691cSlogin         }
108bacd691cSlogin         let mut split_pos: usize = 0;
109bacd691cSlogin         for (pos, elt) in timer_list.iter().enumerate() {
1100d6cf65aSLoGin             if elt.inner().expire_jiffies > inner_guard.expire_jiffies {
111bacd691cSlogin                 split_pos = pos;
112bacd691cSlogin                 break;
113bacd691cSlogin             }
114bacd691cSlogin         }
115bacd691cSlogin         let mut temp_list: LinkedList<Arc<Timer>> = timer_list.split_off(split_pos);
116bacd691cSlogin         timer_list.push_back(inner_guard.self_ref.upgrade().unwrap());
117bacd691cSlogin         timer_list.append(&mut temp_list);
118cde5492fSlogin         drop(inner_guard);
119cde5492fSlogin         drop(timer_list);
120bacd691cSlogin     }
121bacd691cSlogin 
122bacd691cSlogin     #[inline]
123bacd691cSlogin     fn run(&self) {
1240d6cf65aSLoGin         let mut timer = self.inner();
125971462beSGnoCiYeH         timer.triggered = true;
1260d6cf65aSLoGin         let func = timer.timer_func.take();
1270d6cf65aSLoGin         drop(timer);
1280d6cf65aSLoGin         let r = func.map(|mut f| f.run()).unwrap_or(Ok(()));
12936fd0130Shoumkh         if unlikely(r.is_err()) {
13036fd0130Shoumkh             kerror!(
13136fd0130Shoumkh                 "Failed to run timer function: {self:?} {:?}",
1328d72b68dSJomo                 r.as_ref().err().unwrap()
13336fd0130Shoumkh             );
13436fd0130Shoumkh         }
135bacd691cSlogin     }
136971462beSGnoCiYeH 
137971462beSGnoCiYeH     /// ## 判断定时器是否已经触发
138971462beSGnoCiYeH     pub fn timeout(&self) -> bool {
1390d6cf65aSLoGin         self.inner().triggered
140971462beSGnoCiYeH     }
141971462beSGnoCiYeH 
142971462beSGnoCiYeH     /// ## 取消定时器任务
143971462beSGnoCiYeH     pub fn cancel(&self) -> bool {
1440d6cf65aSLoGin         let this_arc = self.inner().self_ref.upgrade().unwrap();
145971462beSGnoCiYeH         TIMER_LIST
1460d6cf65aSLoGin             .lock_irqsave()
1470d6cf65aSLoGin             .extract_if(|x| Arc::ptr_eq(&this_arc, x))
148840045afSLoGin             .for_each(drop);
149971462beSGnoCiYeH         true
150971462beSGnoCiYeH     }
151bacd691cSlogin }
152bacd691cSlogin 
153bacd691cSlogin /// 定时器类型
15436fd0130Shoumkh #[derive(Debug)]
155bacd691cSlogin pub struct InnerTimer {
156bacd691cSlogin     /// 定时器结束时刻
157bacd691cSlogin     pub expire_jiffies: u64,
158bacd691cSlogin     /// 定时器需要执行的函数结构体
1590d6cf65aSLoGin     pub timer_func: Option<Box<dyn TimerFunction>>,
160bacd691cSlogin     /// self_ref
161bacd691cSlogin     self_ref: Weak<Timer>,
162971462beSGnoCiYeH     /// 判断该计时器是否触发
163971462beSGnoCiYeH     triggered: bool,
164bacd691cSlogin }
165bacd691cSlogin 
166bacd691cSlogin #[derive(Debug)]
167bacd691cSlogin pub struct DoTimerSoftirq {
168bacd691cSlogin     running: AtomicBool,
169bacd691cSlogin }
170bacd691cSlogin 
171bacd691cSlogin impl DoTimerSoftirq {
172bacd691cSlogin     pub fn new() -> Self {
173bacd691cSlogin         return DoTimerSoftirq {
174bacd691cSlogin             running: AtomicBool::new(false),
175bacd691cSlogin         };
176bacd691cSlogin     }
177bacd691cSlogin 
178bacd691cSlogin     fn set_run(&self) -> bool {
179bacd691cSlogin         let x = self
180bacd691cSlogin             .running
181bacd691cSlogin             .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed);
182840045afSLoGin         return x.is_ok();
183bacd691cSlogin     }
184bacd691cSlogin 
185bacd691cSlogin     fn clear_run(&self) {
186bacd691cSlogin         self.running.store(false, Ordering::Release);
187bacd691cSlogin     }
188bacd691cSlogin }
189bacd691cSlogin impl SoftirqVec for DoTimerSoftirq {
190bacd691cSlogin     fn run(&self) {
191840045afSLoGin         if !self.set_run() {
192bacd691cSlogin             return;
193bacd691cSlogin         }
194bacd691cSlogin         // 最多只处理TIMER_RUN_CYCLE_THRESHOLD个计时器
195bacd691cSlogin         for _ in 0..TIMER_RUN_CYCLE_THRESHOLD {
196bacd691cSlogin             // kdebug!("DoTimerSoftirq run");
1970d6cf65aSLoGin             let timer_list = TIMER_LIST.try_lock_irqsave();
198cde5492fSlogin             if timer_list.is_err() {
199cde5492fSlogin                 continue;
200cde5492fSlogin             }
201cde5492fSlogin             let mut timer_list = timer_list.unwrap();
202bacd691cSlogin 
203bacd691cSlogin             if timer_list.is_empty() {
204bacd691cSlogin                 break;
205bacd691cSlogin             }
206bacd691cSlogin 
207cde5492fSlogin             let timer_list_front = timer_list.pop_front().unwrap();
208cde5492fSlogin             // kdebug!("to lock timer_list_front");
209cde5492fSlogin             let mut timer_list_front_guard = None;
210cde5492fSlogin             for _ in 0..10 {
2110d6cf65aSLoGin                 let x = timer_list_front.inner.try_lock_irqsave();
212cde5492fSlogin                 if x.is_err() {
213cde5492fSlogin                     continue;
214bacd691cSlogin                 }
215cde5492fSlogin                 timer_list_front_guard = Some(x.unwrap());
216cde5492fSlogin             }
217cde5492fSlogin             if timer_list_front_guard.is_none() {
218cde5492fSlogin                 continue;
219cde5492fSlogin             }
220cde5492fSlogin             let timer_list_front_guard = timer_list_front_guard.unwrap();
22136fd0130Shoumkh             if timer_list_front_guard.expire_jiffies > TIMER_JIFFIES.load(Ordering::SeqCst) {
222cde5492fSlogin                 drop(timer_list_front_guard);
223cde5492fSlogin                 timer_list.push_front(timer_list_front);
224cde5492fSlogin                 break;
225cde5492fSlogin             }
226cde5492fSlogin             drop(timer_list_front_guard);
227cde5492fSlogin             drop(timer_list);
228cde5492fSlogin             timer_list_front.run();
229bacd691cSlogin         }
230bacd691cSlogin 
231bacd691cSlogin         self.clear_run();
232bacd691cSlogin     }
233bacd691cSlogin }
234bacd691cSlogin 
2355b59005fSLoGin /// 初始化系统定时器
2365b59005fSLoGin #[inline(never)]
237bacd691cSlogin pub fn timer_init() {
238bacd691cSlogin     // FIXME 调用register_trap
239bacd691cSlogin     let do_timer_softirq = Arc::new(DoTimerSoftirq::new());
240bacd691cSlogin     softirq_vectors()
241bacd691cSlogin         .register_softirq(SoftirqNumber::TIMER, do_timer_softirq)
242bacd691cSlogin         .expect("Failed to register timer softirq");
24340fe15e0SLoGin     kinfo!("timer initialized successfully");
244bacd691cSlogin }
245bacd691cSlogin 
246bacd691cSlogin /// 计算接下来n毫秒对应的定时器时间片
247bacd691cSlogin pub fn next_n_ms_timer_jiffies(expire_ms: u64) -> u64 {
24836fd0130Shoumkh     return TIMER_JIFFIES.load(Ordering::SeqCst) + 1000 * (expire_ms);
249bacd691cSlogin }
250bacd691cSlogin /// 计算接下来n微秒对应的定时器时间片
251bacd691cSlogin pub fn next_n_us_timer_jiffies(expire_us: u64) -> u64 {
25236fd0130Shoumkh     return TIMER_JIFFIES.load(Ordering::SeqCst) + (expire_us);
253bacd691cSlogin }
254bacd691cSlogin 
255bacd691cSlogin /// @brief 让pcb休眠timeout个jiffies
256bacd691cSlogin ///
257bacd691cSlogin /// @param timeout 需要休眠的时间(单位:jiffies)
258bacd691cSlogin ///
259bacd691cSlogin /// @return Ok(i64) 剩余需要休眠的时间(单位:jiffies)
260bacd691cSlogin ///
261bacd691cSlogin /// @return Err(SystemError) 错误码
262bacd691cSlogin pub fn schedule_timeout(mut timeout: i64) -> Result<i64, SystemError> {
263bacd691cSlogin     // kdebug!("schedule_timeout");
264bacd691cSlogin     if timeout == MAX_TIMEOUT {
265*8cb2e9b3SLoGin         let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
266be8cdf4bSLoGin         ProcessManager::mark_sleep(true).ok();
267*8cb2e9b3SLoGin         drop(irq_guard);
268bacd691cSlogin         sched();
269bacd691cSlogin         return Ok(MAX_TIMEOUT);
270bacd691cSlogin     } else if timeout < 0 {
271bacd691cSlogin         kerror!("timeout can't less than 0");
272bacd691cSlogin         return Err(SystemError::EINVAL);
273bacd691cSlogin     } else {
274bacd691cSlogin         // 禁用中断,防止在这段期间发生调度,造成死锁
27536fd0130Shoumkh         let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
27636fd0130Shoumkh 
27736fd0130Shoumkh         timeout += TIMER_JIFFIES.load(Ordering::SeqCst) as i64;
2781496ba7bSLoGin         let timer = Timer::new(
2791496ba7bSLoGin             WakeUpHelper::new(ProcessManager::current_pcb()),
2801496ba7bSLoGin             timeout as u64,
2811496ba7bSLoGin         );
2821496ba7bSLoGin         ProcessManager::mark_sleep(true).ok();
283bacd691cSlogin         timer.activate();
28436fd0130Shoumkh 
28536fd0130Shoumkh         drop(irq_guard);
286bacd691cSlogin 
287bacd691cSlogin         sched();
28836fd0130Shoumkh         let time_remaining: i64 = timeout - TIMER_JIFFIES.load(Ordering::SeqCst) as i64;
289bacd691cSlogin         if time_remaining >= 0 {
290bacd691cSlogin             // 被提前唤醒,返回剩余时间
291bacd691cSlogin             return Ok(time_remaining);
292bacd691cSlogin         } else {
293bacd691cSlogin             return Ok(0);
294bacd691cSlogin         }
295bacd691cSlogin     }
296bacd691cSlogin }
297bacd691cSlogin 
298bacd691cSlogin pub fn timer_get_first_expire() -> Result<u64, SystemError> {
299bacd691cSlogin     // FIXME
300bacd691cSlogin     // kdebug!("rs_timer_get_first_expire,timer_jif = {:?}", TIMER_JIFFIES);
301bacd691cSlogin     for _ in 0..10 {
302be8cdf4bSLoGin         match TIMER_LIST.try_lock_irqsave() {
303bacd691cSlogin             Ok(timer_list) => {
304bacd691cSlogin                 // kdebug!("rs_timer_get_first_expire TIMER_LIST lock successfully");
305bacd691cSlogin                 if timer_list.is_empty() {
306bacd691cSlogin                     // kdebug!("timer_list is empty");
307bacd691cSlogin                     return Ok(0);
308bacd691cSlogin                 } else {
309bacd691cSlogin                     // kdebug!("timer_list not empty");
3100d6cf65aSLoGin                     return Ok(timer_list.front().unwrap().inner().expire_jiffies);
311bacd691cSlogin                 }
312bacd691cSlogin             }
313bacd691cSlogin             // 加锁失败返回啥??
314bacd691cSlogin             Err(_) => continue,
315bacd691cSlogin         }
316bacd691cSlogin     }
31779a452ceShoumkh     return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
318bacd691cSlogin }
319bacd691cSlogin 
320be8cdf4bSLoGin /// 更新系统时间片
321be8cdf4bSLoGin ///
322be8cdf4bSLoGin /// todo: 这里的实现有问题,貌似把HPET的500us当成了500个jiffies,然后update_wall_time()里面也硬编码了这个500us
3230d6cf65aSLoGin pub fn update_timer_jiffies(add_jiffies: u64, time_us: i64) -> u64 {
32436fd0130Shoumkh     let prev = TIMER_JIFFIES.fetch_add(add_jiffies, Ordering::SeqCst);
32536fd0130Shoumkh     compiler_fence(Ordering::SeqCst);
3260d6cf65aSLoGin     update_wall_time(time_us);
32736fd0130Shoumkh 
32836fd0130Shoumkh     compiler_fence(Ordering::SeqCst);
32936fd0130Shoumkh     return prev + add_jiffies;
330bacd691cSlogin }
33136fd0130Shoumkh 
332bacd691cSlogin pub fn clock() -> u64 {
33336fd0130Shoumkh     return TIMER_JIFFIES.load(Ordering::SeqCst);
334bacd691cSlogin }
335bacd691cSlogin 
336bacd691cSlogin // ====== 以下为给C提供的接口 ======
337bacd691cSlogin 
338bacd691cSlogin #[no_mangle]
339bacd691cSlogin pub extern "C" fn rs_timer_init() {
340bacd691cSlogin     timer_init();
341bacd691cSlogin }
342