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