1 use core::{arch::x86_64::_rdtsc, hint::spin_loop, ptr::null_mut};
2
3 use alloc::{boxed::Box, sync::Arc};
4
5 use crate::{
6 arch::{
7 asm::current::current_pcb,
8 interrupt::{cli, sti},
9 sched::sched,
10 },
11 include::bindings::bindings::{timespec, useconds_t, Cpu_tsc_freq},
12 syscall::SystemError,
13 };
14
15 use super::{
16 timer::{next_n_us_timer_jiffies, Timer, WakeUpHelper},
17 TimeSpec,
18 };
19
20 /// @brief 休眠指定时间(单位:纳秒)
21 ///
22 /// @param sleep_time 指定休眠的时间
23 ///
24 /// @return Ok(TimeSpec) 剩余休眠时间
25 ///
26 /// @return Err(SystemError) 错误码
nano_sleep(sleep_time: TimeSpec) -> Result<TimeSpec, SystemError>27 pub fn nano_sleep(sleep_time: TimeSpec) -> Result<TimeSpec, SystemError> {
28 if sleep_time.tv_nsec < 0 || sleep_time.tv_nsec >= 1000000000 {
29 return Err(SystemError::EINVAL);
30 }
31 // 对于小于500us的时间,使用spin/rdtsc来进行定时
32
33 if sleep_time.tv_nsec < 500000 {
34 let expired_tsc: u64 =
35 unsafe { _rdtsc() + (sleep_time.tv_nsec as u64 * Cpu_tsc_freq) / 1000000000 };
36 while unsafe { _rdtsc() } < expired_tsc {
37 spin_loop()
38 }
39 return Ok(TimeSpec {
40 tv_sec: 0,
41 tv_nsec: 0,
42 });
43 }
44 // 创建定时器
45 let handler: Box<WakeUpHelper> = WakeUpHelper::new(current_pcb());
46 let timer: Arc<Timer> = Timer::new(
47 handler,
48 next_n_us_timer_jiffies((sleep_time.tv_nsec / 1000) as u64),
49 );
50
51 cli();
52 timer.activate();
53 unsafe {
54 current_pcb().mark_sleep_interruptible();
55 }
56 sti();
57
58 sched();
59
60 // TODO: 增加信号唤醒的功能后,返回正确的剩余时间
61
62 return Ok(TimeSpec {
63 tv_sec: 0,
64 tv_nsec: 0,
65 });
66 }
67
68 /// @brief 休眠指定时间(单位:微秒)
69 ///
70 /// @param usec 微秒
71 ///
72 /// @return Ok(TimeSpec) 剩余休眠时间
73 ///
74 /// @return Err(SystemError) 错误码
us_sleep(sleep_time: TimeSpec) -> Result<TimeSpec, SystemError>75 pub fn us_sleep(sleep_time: TimeSpec) -> Result<TimeSpec, SystemError> {
76 match nano_sleep(sleep_time) {
77 Ok(value) => return Ok(value),
78 Err(err) => return Err(err),
79 };
80 }
81
82 //===== 以下为提供给C的接口 =====
83
84 /// @brief 休眠指定时间(单位:纳秒)(提供给C的接口)
85 ///
86 /// @param sleep_time 指定休眠的时间
87 ///
88 /// @param rm_time 剩余休眠时间(传出参数)
89 ///
90 /// @return Ok(i32) 0
91 ///
92 /// @return Err(SystemError) 错误码
93 #[no_mangle]
rs_nanosleep(sleep_time: *const timespec, rm_time: *mut timespec) -> i3294 pub extern "C" fn rs_nanosleep(sleep_time: *const timespec, rm_time: *mut timespec) -> i32 {
95 if sleep_time == null_mut() {
96 return SystemError::EINVAL.to_posix_errno();
97 }
98 let slt_spec = TimeSpec {
99 tv_sec: unsafe { *sleep_time }.tv_sec,
100 tv_nsec: unsafe { *sleep_time }.tv_nsec,
101 };
102
103 match nano_sleep(slt_spec) {
104 Ok(value) => {
105 if rm_time != null_mut() {
106 unsafe { *rm_time }.tv_sec = value.tv_sec;
107 unsafe { *rm_time }.tv_nsec = value.tv_nsec;
108 }
109
110 return 0;
111 }
112 Err(err) => {
113 return err.to_posix_errno();
114 }
115 }
116 }
117
118 /// @brief 休眠指定时间(单位:微秒)(提供给C的接口)
119 ///
120 /// @param usec 微秒
121 ///
122 /// @return Ok(i32) 0
123 ///
124 /// @return Err(SystemError) 错误码
125 #[no_mangle]
rs_usleep(usec: useconds_t) -> i32126 pub extern "C" fn rs_usleep(usec: useconds_t) -> i32 {
127 let sleep_time = TimeSpec {
128 tv_sec: (usec / 1000000) as i64,
129 tv_nsec: ((usec % 1000000) * 1000) as i64,
130 };
131 match us_sleep(sleep_time) {
132 Ok(_) => {
133 return 0;
134 }
135 Err(err) => {
136 return err.to_posix_errno();
137 }
138 };
139 }
140