1 use core::{ 2 ffi::{c_int, c_longlong}, 3 ptr::null_mut, 4 }; 5 6 use crate::{ 7 syscall::{user_access::UserBufferWriter, Syscall, SystemError}, 8 time::{sleep::nanosleep, TimeSpec}, 9 }; 10 11 use super::timekeeping::do_gettimeofday; 12 13 pub type PosixTimeT = c_longlong; 14 pub type PosixSusecondsT = c_int; 15 16 #[repr(C)] 17 #[derive(Default, Debug, Copy, Clone)] 18 pub struct PosixTimeval { 19 pub tv_sec: PosixTimeT, 20 pub tv_usec: PosixSusecondsT, 21 } 22 23 #[repr(C)] 24 #[derive(Default, Debug, Copy, Clone)] 25 /// 当前时区信息 26 pub struct PosixTimeZone { 27 /// 格林尼治相对于当前时区相差的分钟数 28 pub tz_minuteswest: c_int, 29 /// DST矫正时差 30 pub tz_dsttime: c_int, 31 } 32 33 /// 系统时区 暂时写定为东八区 34 pub const SYS_TIMEZONE: PosixTimeZone = PosixTimeZone { 35 tz_minuteswest: -480, 36 tz_dsttime: 0, 37 }; 38 39 impl Syscall { 40 /// @brief 休眠指定时间(单位:纳秒)(提供给C的接口) 41 /// 42 /// @param sleep_time 指定休眠的时间 43 /// 44 /// @param rm_time 剩余休眠时间(传出参数) 45 /// 46 /// @return Ok(i32) 0 47 /// 48 /// @return Err(SystemError) 错误码 49 pub fn nanosleep( 50 sleep_time: *const TimeSpec, 51 rm_time: *mut TimeSpec, 52 ) -> Result<usize, SystemError> { 53 if sleep_time == null_mut() { 54 return Err(SystemError::EFAULT); 55 } 56 let slt_spec = TimeSpec { 57 tv_sec: unsafe { *sleep_time }.tv_sec, 58 tv_nsec: unsafe { *sleep_time }.tv_nsec, 59 }; 60 61 let r: Result<usize, SystemError> = nanosleep(slt_spec).map(|slt_spec| { 62 if rm_time != null_mut() { 63 unsafe { *rm_time }.tv_sec = slt_spec.tv_sec; 64 unsafe { *rm_time }.tv_nsec = slt_spec.tv_nsec; 65 } 66 0 67 }); 68 69 return r; 70 } 71 72 /// 获取cpu时间 73 /// 74 /// todo: 该系统调用与Linux不一致,将来需要删除该系统调用!!! 删的时候记得改C版本的libc 75 pub fn clock() -> Result<usize, SystemError> { 76 return Ok(super::timer::clock() as usize); 77 } 78 79 pub fn gettimeofday( 80 tv: *mut PosixTimeval, 81 timezone: *mut PosixTimeZone, 82 ) -> Result<usize, SystemError> { 83 // TODO; 处理时区信息 84 if tv.is_null() { 85 return Err(SystemError::EFAULT); 86 } 87 let mut tv_buf = 88 UserBufferWriter::new::<PosixTimeval>(tv, core::mem::size_of::<PosixTimeval>(), true)?; 89 90 let tz_buf = if timezone.is_null() { 91 None 92 } else { 93 Some(UserBufferWriter::new::<PosixTimeZone>( 94 timezone, 95 core::mem::size_of::<PosixTimeZone>(), 96 true, 97 )?) 98 }; 99 100 let posix_time = do_gettimeofday(); 101 102 tv_buf.copy_one_to_user(&posix_time, 0)?; 103 104 if let Some(mut tz_buf) = tz_buf { 105 tz_buf.copy_one_to_user(&SYS_TIMEZONE, 0)?; 106 } 107 108 return Ok(0); 109 } 110 } 111