xref: /DragonOS/kernel/src/time/syscall.rs (revision c757940bd61b0125e037a59eb77565e42470201b)
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