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) 错误码 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) 错误码 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] 94 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] 126 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