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