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