use crate::arch::ipc::signal::{SigCode, Signal}; use crate::exception::InterruptArch; use crate::ipc::signal_types::SigType; use crate::process::CurrentIrqArch; use crate::process::Pid; use crate::process::SigInfo; use crate::time::timer::{clock, Jiffies, Timer, TimerFunction}; use alloc::{boxed::Box, sync::Arc}; use core::sync::atomic::compiler_fence; use core::time::Duration; use system_error::SystemError; /// 闹钟结构体 #[derive(Debug)] pub struct AlarmTimer { /// 闹钟内置定时器 pub timer: Arc, /// 闹钟触发时间 expired_second: u64, } impl AlarmTimer { /// # 创建闹钟结构体 /// /// 自定义定时器触发函数和截止时间来创建闹钟结构体 /// /// ## 函数参数 /// /// timer_func:定时器触发函数 /// /// second:设置alarm触发的秒数 /// /// ### 函数返回值 /// /// Self pub fn new(timer_func: Box, second: u64) -> Self { let expired_jiffies = >::from(Duration::from_secs(second)).timer_jiffies(); let result = AlarmTimer { timer: Timer::new(timer_func, expired_jiffies), expired_second: second, }; result } /// # 启动闹钟 pub fn activate(&self) { let timer = self.timer.clone(); timer.activate(); } /// # 初始化目标进程的alarm定时器 /// /// 创建一个闹钟结构体并启动闹钟 /// /// ## 函数参数 /// /// pid:发送消息的目标进程的pid /// /// second:设置alarm触发的秒数 /// /// ### 函数返回值 /// /// AlarmTimer结构体 pub fn alarm_timer_init(pid: Pid, second: u64) -> AlarmTimer { //初始化Timerfunc let timerfunc = AlarmTimerFunc::new(pid); let alarmtimer = AlarmTimer::new(timerfunc, second); alarmtimer.activate(); alarmtimer } /// # 查看闹钟是否触发 pub fn timeout(&self) -> bool { self.timer.timeout() } /// # 返回闹钟定时器剩余时间 pub fn remain(&self) -> Duration { if self.timer.timeout() { Duration::ZERO } else { let now_jiffies = clock(); let end_jiffies = >::from(Duration::from_secs(self.expired_second)) .timer_jiffies(); let remain_second = Duration::from(Jiffies::new(end_jiffies - now_jiffies)); // kdebug!( // "end: {} - now: {} = remain: {}", // end_jiffies, // now_jiffies, // end_jiffies - now_jiffies // ); remain_second } } /// # 取消闹钟 pub fn cancel(&self) { self.timer.cancel(); } } /// # 闹钟TimerFuntion结构体 /// /// ## 结构成员 /// /// pid:发送消息的目标进程的pid #[derive(Debug)] pub struct AlarmTimerFunc { pid: Pid, } impl AlarmTimerFunc { pub fn new(pid: Pid) -> Box { return Box::new(AlarmTimerFunc { pid }); } } impl TimerFunction for AlarmTimerFunc { /// # 闹钟触发函数 /// /// 闹钟触发时,向目标进程发送一个SIGALRM信号 /// /// ## 函数参数 /// /// expired_second:设置alarm触发的秒数 /// /// ### 函数返回值 /// /// Ok(()): 发送成功 fn run(&mut self) -> Result<(), SystemError> { let sig = Signal::SIGALRM; // 初始化signal info let mut info = SigInfo::new(sig, 0, SigCode::Timer, SigType::Alarm(self.pid)); compiler_fence(core::sync::atomic::Ordering::SeqCst); let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; let _retval = sig .send_signal_info(Some(&mut info), self.pid) .map(|x| x as usize)?; compiler_fence(core::sync::atomic::Ordering::SeqCst); drop(irq_guard); Ok(()) } }