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