1 use core::{ 2 ffi::{c_int, c_longlong}, 3 ptr::null_mut, 4 }; 5 6 use num_traits::FromPrimitive; 7 use system_error::SystemError; 8 9 use crate::{ 10 syscall::{user_access::UserBufferWriter, Syscall}, 11 time::{sleep::nanosleep, TimeSpec}, 12 }; 13 14 use super::timekeeping::do_gettimeofday; 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 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) 错误码 75 pub fn nanosleep( 76 sleep_time: *const TimeSpec, 77 rm_time: *mut TimeSpec, 78 ) -> Result<usize, SystemError> { 79 if sleep_time == null_mut() { 80 return Err(SystemError::EFAULT); 81 } 82 let slt_spec = TimeSpec { 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 != null_mut() { 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 101 pub fn clock() -> Result<usize, SystemError> { 102 return Ok(super::timer::clock() as usize); 103 } 104 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 137 pub fn clock_gettime(clock_id: c_int, tp: *mut TimeSpec) -> Result<usize, SystemError> { 138 let clock_id = PosixClockID::try_from(clock_id)?; 139 if clock_id != PosixClockID::Realtime { 140 kwarn!("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 = 146 UserBufferWriter::new::<TimeSpec>(tp, core::mem::size_of::<TimeSpec>(), true)?; 147 148 let posix_time = do_gettimeofday(); 149 150 tp_buf.copy_one_to_user(&posix_time, 0)?; 151 152 return Ok(0); 153 } 154 } 155