1 use core::{ 2 ffi::{c_int, c_longlong}, 3 time::Duration, 4 }; 5 6 use num_traits::FromPrimitive; 7 use system_error::SystemError; 8 9 use crate::{ 10 process::{timer::AlarmTimer, ProcessManager}, 11 syscall::{user_access::UserBufferWriter, Syscall}, 12 time::{sleep::nanosleep, PosixTimeSpec}, 13 }; 14 15 use super::timekeeping::{do_gettimeofday, getnstimeofday}; 16 17 pub type PosixTimeT = c_longlong; 18 pub type PosixSusecondsT = c_int; 19 20 #[repr(C)] 21 #[derive(Default, Debug, Copy, Clone)] 22 pub struct PosixTimeval { 23 pub tv_sec: PosixTimeT, 24 pub tv_usec: PosixSusecondsT, 25 } 26 27 #[repr(C)] 28 #[derive(Default, Debug, Copy, Clone)] 29 /// 当前时区信息 30 pub struct PosixTimeZone { 31 /// 格林尼治相对于当前时区相差的分钟数 32 pub tz_minuteswest: c_int, 33 /// DST矫正时差 34 pub tz_dsttime: c_int, 35 } 36 37 /// 系统时区 暂时写定为东八区 38 pub const SYS_TIMEZONE: PosixTimeZone = PosixTimeZone { 39 tz_minuteswest: -480, 40 tz_dsttime: 0, 41 }; 42 43 /// The IDs of the various system clocks (for POSIX.1b interval timers): 44 #[derive(Debug, Copy, Clone, PartialEq, Eq, FromPrimitive)] 45 pub enum PosixClockID { 46 Realtime = 0, 47 Monotonic = 1, 48 ProcessCPUTimeID = 2, 49 ThreadCPUTimeID = 3, 50 MonotonicRaw = 4, 51 RealtimeCoarse = 5, 52 MonotonicCoarse = 6, 53 Boottime = 7, 54 RealtimeAlarm = 8, 55 BoottimeAlarm = 9, 56 } 57 58 impl TryFrom<i32> for PosixClockID { 59 type Error = SystemError; 60 61 fn try_from(value: i32) -> Result<Self, Self::Error> { 62 <Self as FromPrimitive>::from_i32(value).ok_or(SystemError::EINVAL) 63 } 64 } 65 66 impl Syscall { 67 /// @brief 休眠指定时间(单位:纳秒)(提供给C的接口) 68 /// 69 /// @param sleep_time 指定休眠的时间 70 /// 71 /// @param rm_time 剩余休眠时间(传出参数) 72 /// 73 /// @return Ok(i32) 0 74 /// 75 /// @return Err(SystemError) 错误码 76 pub fn nanosleep( 77 sleep_time: *const PosixTimeSpec, 78 rm_time: *mut PosixTimeSpec, 79 ) -> Result<usize, SystemError> { 80 if sleep_time.is_null() { 81 return Err(SystemError::EFAULT); 82 } 83 let slt_spec = PosixTimeSpec { 84 tv_sec: unsafe { *sleep_time }.tv_sec, 85 tv_nsec: unsafe { *sleep_time }.tv_nsec, 86 }; 87 88 let r: Result<usize, SystemError> = nanosleep(slt_spec).map(|slt_spec| { 89 if !rm_time.is_null() { 90 unsafe { *rm_time }.tv_sec = slt_spec.tv_sec; 91 unsafe { *rm_time }.tv_nsec = slt_spec.tv_nsec; 92 } 93 0 94 }); 95 96 return r; 97 } 98 99 /// 获取cpu时间 100 /// 101 /// todo: 该系统调用与Linux不一致,将来需要删除该系统调用!!! 删的时候记得改C版本的libc 102 pub fn clock() -> Result<usize, SystemError> { 103 return Ok(super::timer::clock() as usize); 104 } 105 106 pub fn gettimeofday( 107 tv: *mut PosixTimeval, 108 timezone: *mut PosixTimeZone, 109 ) -> Result<usize, SystemError> { 110 // TODO; 处理时区信息 111 if tv.is_null() { 112 return Err(SystemError::EFAULT); 113 } 114 let mut tv_buf = 115 UserBufferWriter::new::<PosixTimeval>(tv, core::mem::size_of::<PosixTimeval>(), true)?; 116 117 let tz_buf = if timezone.is_null() { 118 None 119 } else { 120 Some(UserBufferWriter::new::<PosixTimeZone>( 121 timezone, 122 core::mem::size_of::<PosixTimeZone>(), 123 true, 124 )?) 125 }; 126 127 let posix_time = do_gettimeofday(); 128 129 tv_buf.copy_one_to_user(&posix_time, 0)?; 130 131 if let Some(mut tz_buf) = tz_buf { 132 tz_buf.copy_one_to_user(&SYS_TIMEZONE, 0)?; 133 } 134 135 return Ok(0); 136 } 137 138 pub fn clock_gettime(clock_id: c_int, tp: *mut PosixTimeSpec) -> Result<usize, SystemError> { 139 let clock_id = PosixClockID::try_from(clock_id)?; 140 if clock_id != PosixClockID::Realtime { 141 kwarn!("clock_gettime: currently only support Realtime clock, but got {:?}. Defaultly return realtime!!!\n", clock_id); 142 } 143 if tp.is_null() { 144 return Err(SystemError::EFAULT); 145 } 146 let mut tp_buf = UserBufferWriter::new::<PosixTimeSpec>( 147 tp, 148 core::mem::size_of::<PosixTimeSpec>(), 149 true, 150 )?; 151 152 let timespec = getnstimeofday(); 153 154 tp_buf.copy_one_to_user(×pec, 0)?; 155 156 return Ok(0); 157 } 158 /// # alarm函数功能 159 /// 160 /// 设置alarm(单位:秒) 161 /// 162 /// ## 函数参数 163 /// 164 /// expired_second:设置alarm触发的秒数 165 /// 166 /// ### 函数返回值 167 /// 168 /// Ok(usize): 上一个alarm的剩余秒数 169 pub fn alarm(expired_second: u32) -> Result<usize, SystemError> { 170 //初始化second 171 let second = Duration::from_secs(expired_second as u64); 172 let pcb = ProcessManager::current_pcb(); 173 let mut pcb_alarm = pcb.alarm_timer_irqsave(); 174 let alarm = pcb_alarm.as_ref(); 175 //alarm第一次调用 176 if alarm.is_none() { 177 //注册alarm定时器 178 let pid = ProcessManager::current_pid(); 179 let new_alarm = Some(AlarmTimer::alarm_timer_init(pid, 0)); 180 *pcb_alarm = new_alarm; 181 drop(pcb_alarm); 182 return Ok(0); 183 } 184 //查询上一个alarm的剩余时间和重新注册alarm 185 let alarmtimer = alarm.unwrap(); 186 let remain = alarmtimer.remain(); 187 if second.is_zero() { 188 alarmtimer.cancel(); 189 } 190 if !alarmtimer.timeout() { 191 alarmtimer.cancel(); 192 } 193 let pid = ProcessManager::current_pid(); 194 let new_alarm = Some(AlarmTimer::alarm_timer_init(pid, second.as_secs())); 195 *pcb_alarm = new_alarm; 196 drop(pcb_alarm); 197 return Ok(remain.as_secs() as usize); 198 } 199 } 200