xref: /DragonOS/kernel/src/process/timer.rs (revision fbd63a301c5648f906eeb802f10ac03518ba1264)
1*fbd63a30SSMALLC use crate::arch::ipc::signal::{SigCode, Signal};
2*fbd63a30SSMALLC use crate::exception::InterruptArch;
3*fbd63a30SSMALLC use crate::ipc::signal_types::SigType;
4*fbd63a30SSMALLC use crate::process::CurrentIrqArch;
5*fbd63a30SSMALLC use crate::process::Pid;
6*fbd63a30SSMALLC use crate::process::SigInfo;
7*fbd63a30SSMALLC use crate::time::timer::{clock, Jiffies, Timer, TimerFunction};
8*fbd63a30SSMALLC use alloc::{boxed::Box, sync::Arc};
9*fbd63a30SSMALLC use core::sync::atomic::compiler_fence;
10*fbd63a30SSMALLC use core::time::Duration;
11*fbd63a30SSMALLC use system_error::SystemError;
12*fbd63a30SSMALLC 
13*fbd63a30SSMALLC /// 闹钟结构体
14*fbd63a30SSMALLC #[derive(Debug)]
15*fbd63a30SSMALLC pub struct AlarmTimer {
16*fbd63a30SSMALLC     /// 闹钟内置定时器
17*fbd63a30SSMALLC     pub timer: Arc<Timer>,
18*fbd63a30SSMALLC     /// 闹钟触发时间
19*fbd63a30SSMALLC     expired_second: u64,
20*fbd63a30SSMALLC }
21*fbd63a30SSMALLC 
22*fbd63a30SSMALLC impl AlarmTimer {
23*fbd63a30SSMALLC     /// # 创建闹钟结构体
24*fbd63a30SSMALLC     ///
25*fbd63a30SSMALLC     /// 自定义定时器触发函数和截止时间来创建闹钟结构体
26*fbd63a30SSMALLC     ///
27*fbd63a30SSMALLC     /// ## 函数参数
28*fbd63a30SSMALLC     ///
29*fbd63a30SSMALLC     /// timer_func:定时器触发函数
30*fbd63a30SSMALLC     ///
31*fbd63a30SSMALLC     /// second:设置alarm触发的秒数
32*fbd63a30SSMALLC     ///
33*fbd63a30SSMALLC     /// ### 函数返回值
34*fbd63a30SSMALLC     ///
35*fbd63a30SSMALLC     /// Self
36*fbd63a30SSMALLC     pub fn new(timer_func: Box<dyn TimerFunction>, second: u64) -> Self {
37*fbd63a30SSMALLC         let expired_jiffies =
38*fbd63a30SSMALLC             <Jiffies as From<Duration>>::from(Duration::from_secs(second)).timer_jiffies();
39*fbd63a30SSMALLC         let result = AlarmTimer {
40*fbd63a30SSMALLC             timer: Timer::new(timer_func, expired_jiffies),
41*fbd63a30SSMALLC             expired_second: second,
42*fbd63a30SSMALLC         };
43*fbd63a30SSMALLC         result
44*fbd63a30SSMALLC     }
45*fbd63a30SSMALLC     /// # 启动闹钟
46*fbd63a30SSMALLC     pub fn activate(&self) {
47*fbd63a30SSMALLC         let timer = self.timer.clone();
48*fbd63a30SSMALLC         timer.activate();
49*fbd63a30SSMALLC     }
50*fbd63a30SSMALLC 
51*fbd63a30SSMALLC     /// # 初始化目标进程的alarm定时器
52*fbd63a30SSMALLC     ///
53*fbd63a30SSMALLC     /// 创建一个闹钟结构体并启动闹钟
54*fbd63a30SSMALLC     ///
55*fbd63a30SSMALLC     /// ## 函数参数
56*fbd63a30SSMALLC     ///
57*fbd63a30SSMALLC     /// pid:发送消息的目标进程的pid
58*fbd63a30SSMALLC     ///
59*fbd63a30SSMALLC     /// second:设置alarm触发的秒数
60*fbd63a30SSMALLC     ///
61*fbd63a30SSMALLC     /// ### 函数返回值
62*fbd63a30SSMALLC     ///
63*fbd63a30SSMALLC     /// AlarmTimer结构体
64*fbd63a30SSMALLC     pub fn alarm_timer_init(pid: Pid, second: u64) -> AlarmTimer {
65*fbd63a30SSMALLC         //初始化Timerfunc
66*fbd63a30SSMALLC         let timerfunc = AlarmTimerFunc::new(pid);
67*fbd63a30SSMALLC         let alarmtimer = AlarmTimer::new(timerfunc, second);
68*fbd63a30SSMALLC         alarmtimer.activate();
69*fbd63a30SSMALLC         alarmtimer
70*fbd63a30SSMALLC     }
71*fbd63a30SSMALLC 
72*fbd63a30SSMALLC     /// # 查看闹钟是否触发
73*fbd63a30SSMALLC     pub fn timeout(&self) -> bool {
74*fbd63a30SSMALLC         self.timer.timeout()
75*fbd63a30SSMALLC     }
76*fbd63a30SSMALLC 
77*fbd63a30SSMALLC     /// # 返回闹钟定时器剩余时间
78*fbd63a30SSMALLC     pub fn remain(&self) -> Duration {
79*fbd63a30SSMALLC         if self.timer.timeout() {
80*fbd63a30SSMALLC             Duration::ZERO
81*fbd63a30SSMALLC         } else {
82*fbd63a30SSMALLC             let now_jiffies = clock();
83*fbd63a30SSMALLC             let end_jiffies =
84*fbd63a30SSMALLC                 <Jiffies as From<Duration>>::from(Duration::from_secs(self.expired_second))
85*fbd63a30SSMALLC                     .timer_jiffies();
86*fbd63a30SSMALLC             let remain_second = Duration::from(Jiffies::new(end_jiffies - now_jiffies));
87*fbd63a30SSMALLC             // kdebug!(
88*fbd63a30SSMALLC             //     "end: {} - now: {} = remain: {}",
89*fbd63a30SSMALLC             //     end_jiffies,
90*fbd63a30SSMALLC             //     now_jiffies,
91*fbd63a30SSMALLC             //     end_jiffies - now_jiffies
92*fbd63a30SSMALLC             // );
93*fbd63a30SSMALLC             remain_second
94*fbd63a30SSMALLC         }
95*fbd63a30SSMALLC     }
96*fbd63a30SSMALLC     /// # 取消闹钟
97*fbd63a30SSMALLC     pub fn cancel(&self) {
98*fbd63a30SSMALLC         self.timer.cancel();
99*fbd63a30SSMALLC     }
100*fbd63a30SSMALLC }
101*fbd63a30SSMALLC 
102*fbd63a30SSMALLC /// # 闹钟TimerFuntion结构体
103*fbd63a30SSMALLC ///
104*fbd63a30SSMALLC /// ## 结构成员
105*fbd63a30SSMALLC ///
106*fbd63a30SSMALLC /// pid:发送消息的目标进程的pid
107*fbd63a30SSMALLC #[derive(Debug)]
108*fbd63a30SSMALLC pub struct AlarmTimerFunc {
109*fbd63a30SSMALLC     pid: Pid,
110*fbd63a30SSMALLC }
111*fbd63a30SSMALLC 
112*fbd63a30SSMALLC impl AlarmTimerFunc {
113*fbd63a30SSMALLC     pub fn new(pid: Pid) -> Box<AlarmTimerFunc> {
114*fbd63a30SSMALLC         return Box::new(AlarmTimerFunc { pid });
115*fbd63a30SSMALLC     }
116*fbd63a30SSMALLC }
117*fbd63a30SSMALLC 
118*fbd63a30SSMALLC impl TimerFunction for AlarmTimerFunc {
119*fbd63a30SSMALLC     /// # 闹钟触发函数
120*fbd63a30SSMALLC     ///
121*fbd63a30SSMALLC     /// 闹钟触发时,向目标进程发送一个SIGALRM信号
122*fbd63a30SSMALLC     ///
123*fbd63a30SSMALLC     /// ## 函数参数
124*fbd63a30SSMALLC     ///
125*fbd63a30SSMALLC     /// expired_second:设置alarm触发的秒数
126*fbd63a30SSMALLC     ///
127*fbd63a30SSMALLC     /// ### 函数返回值
128*fbd63a30SSMALLC     ///
129*fbd63a30SSMALLC     /// Ok(()): 发送成功
130*fbd63a30SSMALLC     fn run(&mut self) -> Result<(), SystemError> {
131*fbd63a30SSMALLC         let sig = Signal::SIGALRM;
132*fbd63a30SSMALLC         // 初始化signal info
133*fbd63a30SSMALLC         let mut info = SigInfo::new(sig, 0, SigCode::Timer, SigType::Alarm(self.pid));
134*fbd63a30SSMALLC 
135*fbd63a30SSMALLC         compiler_fence(core::sync::atomic::Ordering::SeqCst);
136*fbd63a30SSMALLC         let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
137*fbd63a30SSMALLC         let _retval = sig
138*fbd63a30SSMALLC             .send_signal_info(Some(&mut info), self.pid)
139*fbd63a30SSMALLC             .map(|x| x as usize)?;
140*fbd63a30SSMALLC         compiler_fence(core::sync::atomic::Ordering::SeqCst);
141*fbd63a30SSMALLC         drop(irq_guard);
142*fbd63a30SSMALLC         Ok(())
143*fbd63a30SSMALLC     }
144*fbd63a30SSMALLC }
145