1 use core::{ 2 ffi::{c_int, c_longlong}, 3 ptr::null_mut, 4 }; 5 6 use crate::{ 7 syscall::{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)] 18 pub struct PosixTimeval { 19 pub tv_sec: PosixTimeT, 20 pub tv_usec: PosixSusecondsT, 21 } 22 23 #[repr(C)] 24 #[derive(Default, Debug)] 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 // kdebug!("enter sys_do_gettimeofday"); 85 if tv == null_mut() { 86 return Err(SystemError::EFAULT); 87 } 88 let posix_time = do_gettimeofday(); 89 unsafe { 90 (*tv).tv_sec = posix_time.tv_sec; 91 (*tv).tv_usec = posix_time.tv_usec; 92 } 93 94 if !timezone.is_null() { 95 unsafe { 96 *timezone = SYS_TIMEZONE; 97 } 98 } 99 // kdebug!("exit sys_do_gettimeofday"); 100 return Ok(0); 101 } 102 } 103