starry_api/imp/task/
schedule.rs

1use axerrno::{LinuxError, LinuxResult};
2use linux_raw_sys::general::timespec;
3
4use crate::{
5    ptr::{UserConstPtr, UserPtr, nullable},
6    time::TimeValueLike,
7};
8
9pub fn sys_sched_yield() -> LinuxResult<isize> {
10    axtask::yield_now();
11    Ok(0)
12}
13
14/// Sleep some nanoseconds
15///
16/// TODO: should be woken by signals, and set errno
17pub fn sys_nanosleep(req: UserConstPtr<timespec>, rem: UserPtr<timespec>) -> LinuxResult<isize> {
18    let req = req.get_as_ref()?;
19
20    if req.tv_nsec < 0 || req.tv_nsec > 999_999_999 || req.tv_sec < 0 {
21        return Err(LinuxError::EINVAL);
22    }
23
24    let dur = req.to_time_value();
25    debug!("sys_nanosleep <= {:?}", dur);
26
27    let now = axhal::time::monotonic_time();
28
29    axtask::sleep(dur);
30
31    let after = axhal::time::monotonic_time();
32    let actual = after - now;
33
34    if let Some(diff) = dur.checked_sub(actual) {
35        if let Some(rem) = nullable!(rem.get_as_mut())? {
36            *rem = timespec::from_time_value(diff);
37        }
38        Err(LinuxError::EINTR)
39    } else {
40        Ok(0)
41    }
42}