mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-29 14:53:24 +00:00
Add syscall nanosleep
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
ee740020d0
commit
1435dd0896
@ -27,7 +27,6 @@ use crate::{
|
|||||||
chown::{sys_chown, sys_fchown, sys_fchownat, sys_lchown},
|
chown::{sys_chown, sys_fchown, sys_fchownat, sys_lchown},
|
||||||
chroot::sys_chroot,
|
chroot::sys_chroot,
|
||||||
clock_gettime::sys_clock_gettime,
|
clock_gettime::sys_clock_gettime,
|
||||||
clock_nanosleep::sys_clock_nanosleep,
|
|
||||||
clone::sys_clone,
|
clone::sys_clone,
|
||||||
close::sys_close,
|
close::sys_close,
|
||||||
dup::{sys_dup, sys_dup2},
|
dup::{sys_dup, sys_dup2},
|
||||||
@ -59,6 +58,7 @@ use crate::{
|
|||||||
mmap::sys_mmap,
|
mmap::sys_mmap,
|
||||||
mprotect::sys_mprotect,
|
mprotect::sys_mprotect,
|
||||||
munmap::sys_munmap,
|
munmap::sys_munmap,
|
||||||
|
nanosleep::{sys_clock_nanosleep, sys_nanosleep},
|
||||||
open::{sys_open, sys_openat},
|
open::{sys_open, sys_openat},
|
||||||
pause::sys_pause,
|
pause::sys_pause,
|
||||||
pipe::{sys_pipe, sys_pipe2},
|
pipe::{sys_pipe, sys_pipe2},
|
||||||
@ -107,7 +107,6 @@ mod chmod;
|
|||||||
mod chown;
|
mod chown;
|
||||||
mod chroot;
|
mod chroot;
|
||||||
mod clock_gettime;
|
mod clock_gettime;
|
||||||
mod clock_nanosleep;
|
|
||||||
mod clone;
|
mod clone;
|
||||||
mod close;
|
mod close;
|
||||||
mod connect;
|
mod connect;
|
||||||
@ -150,6 +149,7 @@ mod mkdir;
|
|||||||
mod mmap;
|
mod mmap;
|
||||||
mod mprotect;
|
mod mprotect;
|
||||||
mod munmap;
|
mod munmap;
|
||||||
|
mod nanosleep;
|
||||||
mod open;
|
mod open;
|
||||||
mod pause;
|
mod pause;
|
||||||
mod pipe;
|
mod pipe;
|
||||||
@ -261,6 +261,7 @@ define_syscall_nums!(
|
|||||||
SYS_DUP = 32,
|
SYS_DUP = 32,
|
||||||
SYS_DUP2 = 33,
|
SYS_DUP2 = 33,
|
||||||
SYS_PAUSE = 34,
|
SYS_PAUSE = 34,
|
||||||
|
SYS_NANOSLEEP = 35,
|
||||||
SYS_ALARM = 37,
|
SYS_ALARM = 37,
|
||||||
SYS_GETPID = 39,
|
SYS_GETPID = 39,
|
||||||
SYS_SOCKET = 41,
|
SYS_SOCKET = 41,
|
||||||
@ -449,6 +450,7 @@ pub fn syscall_dispatch(
|
|||||||
SYS_DUP => syscall_handler!(1, sys_dup, args),
|
SYS_DUP => syscall_handler!(1, sys_dup, args),
|
||||||
SYS_DUP2 => syscall_handler!(2, sys_dup2, args),
|
SYS_DUP2 => syscall_handler!(2, sys_dup2, args),
|
||||||
SYS_PAUSE => syscall_handler!(0, sys_pause),
|
SYS_PAUSE => syscall_handler!(0, sys_pause),
|
||||||
|
SYS_NANOSLEEP => syscall_handler!(2, sys_nanosleep, args),
|
||||||
SYS_ALARM => syscall_handler!(1, sys_alarm, args),
|
SYS_ALARM => syscall_handler!(1, sys_alarm, args),
|
||||||
SYS_GETPID => syscall_handler!(0, sys_getpid),
|
SYS_GETPID => syscall_handler!(0, sys_getpid),
|
||||||
SYS_SOCKET => syscall_handler!(3, sys_socket, args),
|
SYS_SOCKET => syscall_handler!(3, sys_socket, args),
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use core::time::Duration;
|
use core::time::Duration;
|
||||||
|
|
||||||
use super::{SyscallReturn, SYS_CLOCK_NANOSLEEP};
|
use super::{SyscallReturn, SYS_CLOCK_NANOSLEEP, SYS_NANOSLEEP};
|
||||||
use crate::{
|
use crate::{
|
||||||
log_syscall_entry,
|
log_syscall_entry,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
@ -11,6 +11,16 @@ use crate::{
|
|||||||
util::{read_val_from_user, write_val_to_user},
|
util::{read_val_from_user, write_val_to_user},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub fn sys_nanosleep(
|
||||||
|
request_timespec_addr: Vaddr,
|
||||||
|
remain_timespec_addr: Vaddr,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
|
log_syscall_entry!(SYS_NANOSLEEP);
|
||||||
|
let clock_id = ClockID::CLOCK_MONOTONIC;
|
||||||
|
|
||||||
|
do_clock_nanosleep(clock_id, false, request_timespec_addr, remain_timespec_addr)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn sys_clock_nanosleep(
|
pub fn sys_clock_nanosleep(
|
||||||
clockid: clockid_t,
|
clockid: clockid_t,
|
||||||
flags: i32,
|
flags: i32,
|
||||||
@ -19,7 +29,7 @@ pub fn sys_clock_nanosleep(
|
|||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
log_syscall_entry!(SYS_CLOCK_NANOSLEEP);
|
log_syscall_entry!(SYS_CLOCK_NANOSLEEP);
|
||||||
let clock_id = ClockID::try_from(clockid)?;
|
let clock_id = ClockID::try_from(clockid)?;
|
||||||
let abs_time = if flags == 0 {
|
let is_abs_time = if flags == 0 {
|
||||||
false
|
false
|
||||||
} else if flags == TIMER_ABSTIME {
|
} else if flags == TIMER_ABSTIME {
|
||||||
true
|
true
|
||||||
@ -27,37 +37,57 @@ pub fn sys_clock_nanosleep(
|
|||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
|
|
||||||
let duration = {
|
do_clock_nanosleep(
|
||||||
|
clock_id,
|
||||||
|
is_abs_time,
|
||||||
|
request_timespec_addr,
|
||||||
|
remain_timespec_addr,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_clock_nanosleep(
|
||||||
|
clock_id: ClockID,
|
||||||
|
is_abs_time: bool,
|
||||||
|
request_timespec_addr: Vaddr,
|
||||||
|
remain_timespec_addr: Vaddr,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
|
let request_time = {
|
||||||
let timespec = read_val_from_user::<timespec_t>(request_timespec_addr)?;
|
let timespec = read_val_from_user::<timespec_t>(request_timespec_addr)?;
|
||||||
if abs_time {
|
|
||||||
todo!("deal with abs time");
|
|
||||||
}
|
|
||||||
Duration::from(timespec)
|
Duration::from(timespec)
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"clockid = {:?}, abs_time = {}, duration = {:?}, remain_timespec_addr = 0x{:x}",
|
"clockid = {:?}, is_abs_time = {}, request_time = {:?}, remain_timespec_addr = 0x{:x}",
|
||||||
clock_id, abs_time, duration, remain_timespec_addr
|
clock_id, is_abs_time, request_time, remain_timespec_addr
|
||||||
);
|
);
|
||||||
|
|
||||||
let start_time = now_as_duration(&clock_id)?;
|
let start_time = now_as_duration(&clock_id)?;
|
||||||
|
let timeout = if is_abs_time {
|
||||||
|
if request_time < start_time {
|
||||||
|
return Ok(SyscallReturn::Return(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
request_time - start_time
|
||||||
|
} else {
|
||||||
|
request_time
|
||||||
|
};
|
||||||
|
|
||||||
// FIXME: sleeping thread can only be interrupted by signals that will call signal handler or terminate
|
// FIXME: sleeping thread can only be interrupted by signals that will call signal handler or terminate
|
||||||
// current process. i.e., the signals that should be ignored will not interrupt sleeping thread.
|
// current process. i.e., the signals that should be ignored will not interrupt sleeping thread.
|
||||||
let pauser = Pauser::new();
|
let pauser = Pauser::new();
|
||||||
|
|
||||||
let res = pauser.pause_until_or_timeout(|| None, &duration);
|
let res = pauser.pause_until_or_timeout(|| None, &timeout);
|
||||||
match res {
|
match res {
|
||||||
Err(e) if e.error() == Errno::ETIME => Ok(SyscallReturn::Return(0)),
|
Err(e) if e.error() == Errno::ETIME => Ok(SyscallReturn::Return(0)),
|
||||||
Err(e) if e.error() == Errno::EINTR => {
|
Err(e) if e.error() == Errno::EINTR => {
|
||||||
let end_time = now_as_duration(&clock_id)?;
|
let end_time = now_as_duration(&clock_id)?;
|
||||||
|
|
||||||
if end_time >= start_time + duration {
|
if end_time >= start_time + timeout {
|
||||||
return Ok(SyscallReturn::Return(0));
|
return Ok(SyscallReturn::Return(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
if remain_timespec_addr != 0 {
|
if remain_timespec_addr != 0 && !is_abs_time {
|
||||||
let remaining_duration = (start_time + duration) - end_time;
|
let remaining_duration = (start_time + timeout) - end_time;
|
||||||
let remaining_timespec = timespec_t::from(remaining_duration);
|
let remaining_timespec = timespec_t::from(remaining_duration);
|
||||||
write_val_to_user(remain_timespec_addr, &remaining_timespec)?;
|
write_val_to_user(remain_timespec_addr, &remaining_timespec)?;
|
||||||
}
|
}
|
Reference in New Issue
Block a user