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