1 use core::{ 2 ffi::{c_int, c_longlong}, 3 ptr::null_mut, 4 }; 5 6 use num_traits::FromPrimitive; 7 8 use crate::{ 9 syscall::{user_access::UserBufferWriter, Syscall, SystemError}, 10 time::{sleep::nanosleep, TimeSpec}, 11 }; 12 13 use super::timekeeping::do_gettimeofday; 14 15 pub type PosixTimeT = c_longlong; 16 pub type PosixSusecondsT = c_int; 17 18 #[repr(C)] 19 #[derive(Default, Debug, Copy, Clone)] 20 pub struct PosixTimeval { 21 pub tv_sec: PosixTimeT, 22 pub tv_usec: PosixSusecondsT, 23 } 24 25 #[repr(C)] 26 #[derive(Default, Debug, Copy, Clone)] 27 /// 当前时区信息 28 pub struct PosixTimeZone { 29 /// 格林尼治相对于当前时区相差的分钟数 30 pub tz_minuteswest: c_int, 31 /// DST矫正时差 32 pub tz_dsttime: c_int, 33 } 34 35 /// 系统时区 暂时写定为东八区 36 pub const SYS_TIMEZONE: PosixTimeZone = PosixTimeZone { 37 tz_minuteswest: -480, 38 tz_dsttime: 0, 39 }; 40 41 /// The IDs of the various system clocks (for POSIX.1b interval timers): 42 #[derive(Debug, Copy, Clone, PartialEq, Eq, FromPrimitive)] 43 pub enum PosixClockID { 44 Realtime = 0, 45 Monotonic = 1, 46 ProcessCPUTimeID = 2, 47 ThreadCPUTimeID = 3, 48 MonotonicRaw = 4, 49 RealtimeCoarse = 5, 50 MonotonicCoarse = 6, 51 Boottime = 7, 52 RealtimeAlarm = 8, 53 BoottimeAlarm = 9, 54 } 55 56 impl TryFrom<i32> for PosixClockID { 57 type Error = SystemError; 58 59 fn try_from(value: i32) -> Result<Self, Self::Error> { 60 <Self as FromPrimitive>::from_i32(value).ok_or(SystemError::EINVAL) 61 } 62 } 63 64 impl Syscall { 65 /// @brief 休眠指定时间(单位:纳秒)(提供给C的接口) 66 /// 67 /// @param sleep_time 指定休眠的时间 68 /// 69 /// @param rm_time 剩余休眠时间(传出参数) 70 /// 71 /// @return Ok(i32) 0 72 /// 73 /// @return Err(SystemError) 错误码 74 pub fn nanosleep( 75 sleep_time: *const TimeSpec, 76 rm_time: *mut TimeSpec, 77 ) -> Result<usize, SystemError> { 78 if sleep_time == null_mut() { 79 return Err(SystemError::EFAULT); 80 } 81 let slt_spec = TimeSpec { 82 tv_sec: unsafe { *sleep_time }.tv_sec, 83 tv_nsec: unsafe { *sleep_time }.tv_nsec, 84 }; 85 86 let r: Result<usize, SystemError> = nanosleep(slt_spec).map(|slt_spec| { 87 if rm_time != null_mut() { 88 unsafe { *rm_time }.tv_sec = slt_spec.tv_sec; 89 unsafe { *rm_time }.tv_nsec = slt_spec.tv_nsec; 90 } 91 0 92 }); 93 94 return r; 95 } 96 97 /// 获取cpu时间 98 /// 99 /// todo: 该系统调用与Linux不一致,将来需要删除该系统调用!!! 删的时候记得改C版本的libc 100 pub fn clock() -> Result<usize, SystemError> { 101 return Ok(super::timer::clock() as usize); 102 } 103 104 pub fn gettimeofday( 105 tv: *mut PosixTimeval, 106 timezone: *mut PosixTimeZone, 107 ) -> Result<usize, SystemError> { 108 // TODO; 处理时区信息 109 if tv.is_null() { 110 return Err(SystemError::EFAULT); 111 } 112 let mut tv_buf = 113 UserBufferWriter::new::<PosixTimeval>(tv, core::mem::size_of::<PosixTimeval>(), true)?; 114 115 let tz_buf = if timezone.is_null() { 116 None 117 } else { 118 Some(UserBufferWriter::new::<PosixTimeZone>( 119 timezone, 120 core::mem::size_of::<PosixTimeZone>(), 121 true, 122 )?) 123 }; 124 125 let posix_time = do_gettimeofday(); 126 127 tv_buf.copy_one_to_user(&posix_time, 0)?; 128 129 if let Some(mut tz_buf) = tz_buf { 130 tz_buf.copy_one_to_user(&SYS_TIMEZONE, 0)?; 131 } 132 133 return Ok(0); 134 } 135 136 pub fn clock_gettime(clock_id: c_int, tp: *mut TimeSpec) -> Result<usize, SystemError> { 137 let clock_id = PosixClockID::try_from(clock_id)?; 138 if clock_id != PosixClockID::Realtime { 139 kwarn!("clock_gettime: currently only support Realtime clock, but got {:?}. Defaultly return realtime!!!\n", clock_id); 140 } 141 if tp.is_null() { 142 return Err(SystemError::EFAULT); 143 } 144 let mut tp_buf = 145 UserBufferWriter::new::<TimeSpec>(tp, core::mem::size_of::<TimeSpec>(), true)?; 146 147 let posix_time = do_gettimeofday(); 148 149 tp_buf.copy_one_to_user(&posix_time, 0)?; 150 151 return Ok(0); 152 } 153 } 154