14fda81ceSLoGin use core::hint::spin_loop;
2bacd691cSlogin
3bacd691cSlogin use alloc::{boxed::Box, sync::Arc};
491e9d4abSLoGin use system_error::SystemError;
5bacd691cSlogin
6bacd691cSlogin use crate::{
7f0c87a89SGnoCiYeH arch::{CurrentIrqArch, CurrentTimeArch},
8ab5c8ca4Slogin exception::InterruptArch,
91496ba7bSLoGin process::ProcessManager,
10f0c87a89SGnoCiYeH sched::{schedule, SchedMode},
118612b6ceSLoGin time::timekeeping::getnstimeofday,
12bacd691cSlogin };
13bacd691cSlogin
14bacd691cSlogin use super::{
15bacd691cSlogin timer::{next_n_us_timer_jiffies, Timer, WakeUpHelper},
16*6fc066acSJomo PosixTimeSpec, TimeArch,
17bacd691cSlogin };
18bacd691cSlogin
19bacd691cSlogin /// @brief 休眠指定时间(单位:纳秒)
20bacd691cSlogin ///
21bacd691cSlogin /// @param sleep_time 指定休眠的时间
22bacd691cSlogin ///
23bacd691cSlogin /// @return Ok(TimeSpec) 剩余休眠时间
24bacd691cSlogin ///
25bacd691cSlogin /// @return Err(SystemError) 错误码
nanosleep(sleep_time: PosixTimeSpec) -> Result<PosixTimeSpec, SystemError>26*6fc066acSJomo pub fn nanosleep(sleep_time: PosixTimeSpec) -> Result<PosixTimeSpec, SystemError> {
27bacd691cSlogin if sleep_time.tv_nsec < 0 || sleep_time.tv_nsec >= 1000000000 {
28bacd691cSlogin return Err(SystemError::EINVAL);
29bacd691cSlogin }
30bacd691cSlogin // 对于小于500us的时间,使用spin/rdtsc来进行定时
318612b6ceSLoGin if sleep_time.tv_nsec < 500000 && sleep_time.tv_sec == 0 {
328cb2e9b3SLoGin let expired_tsc: usize = CurrentTimeArch::cal_expire_cycles(sleep_time.tv_nsec as usize);
338cb2e9b3SLoGin while CurrentTimeArch::get_cycles() < expired_tsc {
34bacd691cSlogin spin_loop()
35bacd691cSlogin }
36*6fc066acSJomo return Ok(PosixTimeSpec {
37bacd691cSlogin tv_sec: 0,
38bacd691cSlogin tv_nsec: 0,
39bacd691cSlogin });
40bacd691cSlogin }
418612b6ceSLoGin
428612b6ceSLoGin let total_sleep_time_us: u64 =
438612b6ceSLoGin sleep_time.tv_sec as u64 * 1000000 + sleep_time.tv_nsec as u64 / 1000;
44bacd691cSlogin // 创建定时器
451496ba7bSLoGin let handler: Box<WakeUpHelper> = WakeUpHelper::new(ProcessManager::current_pcb());
468612b6ceSLoGin let timer: Arc<Timer> = Timer::new(handler, next_n_us_timer_jiffies(total_sleep_time_us));
47bacd691cSlogin
48ab5c8ca4Slogin let irq_guard: crate::exception::IrqFlagsGuard =
49ab5c8ca4Slogin unsafe { CurrentIrqArch::save_and_disable_irq() };
501496ba7bSLoGin ProcessManager::mark_sleep(true).ok();
518612b6ceSLoGin
528612b6ceSLoGin let start_time = getnstimeofday();
53bacd691cSlogin timer.activate();
541496ba7bSLoGin
55ab5c8ca4Slogin drop(irq_guard);
56f0c87a89SGnoCiYeH schedule(SchedMode::SM_NONE);
57bacd691cSlogin
588612b6ceSLoGin let end_time = getnstimeofday();
598612b6ceSLoGin // 返回正确的剩余时间
608612b6ceSLoGin let real_sleep_time = end_time - start_time;
61*6fc066acSJomo let rm_time: PosixTimeSpec = (sleep_time - real_sleep_time.into()).into();
62bacd691cSlogin
638612b6ceSLoGin return Ok(rm_time);
64bacd691cSlogin }
65