diff --git a/kernel/aster-nix/src/syscall/arch/x86.rs b/kernel/aster-nix/src/syscall/arch/x86.rs index c3f00aa99..fb7e0fdb1 100644 --- a/kernel/aster-nix/src/syscall/arch/x86.rs +++ b/kernel/aster-nix/src/syscall/arch/x86.rs @@ -40,6 +40,7 @@ use crate::syscall::{ getrandom::sys_getrandom, getresgid::sys_getresgid, getresuid::sys_getresuid, + getrusage::sys_getrusage, getsid::sys_getsid, getsockname::sys_getsockname, getsockopt::sys_getsockopt, @@ -172,7 +173,7 @@ impl_syscall_nums_and_dispatch_fn! { SYS_FORK = 57 => sys_fork(args[..0], &context); SYS_EXECVE = 59 => sys_execve(args[..3], &mut context); SYS_EXIT = 60 => sys_exit(args[..1]); - SYS_WAIT4 = 61 => sys_wait4(args[..3]); + SYS_WAIT4 = 61 => sys_wait4(args[..4]); SYS_KILL = 62 => sys_kill(args[..2]); SYS_UNAME = 63 => sys_uname(args[..1]); SYS_FCNTL = 72 => sys_fcntl(args[..3]); @@ -197,6 +198,7 @@ impl_syscall_nums_and_dispatch_fn! { SYS_LCHOWN = 94 => sys_lchown(args[..3]); SYS_UMASK = 95 => sys_umask(args[..1]); SYS_GETTIMEOFDAY = 96 => sys_gettimeofday(args[..1]); + SYS_GETRUSAGE = 98 => sys_getrusage(args[..2]); SYS_GETUID = 102 => sys_getuid(args[..0]); SYS_GETGID = 104 => sys_getgid(args[..0]); SYS_SETUID = 105 => sys_setuid(args[..1]); diff --git a/kernel/aster-nix/src/syscall/getrusage.rs b/kernel/aster-nix/src/syscall/getrusage.rs new file mode 100644 index 000000000..fb542f3d8 --- /dev/null +++ b/kernel/aster-nix/src/syscall/getrusage.rs @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: MPL-2.0 + +#![allow(non_camel_case_types)] + +use int_to_c_enum::TryFromInt; + +use super::SyscallReturn; +use crate::{ + prelude::*, process::posix_thread::PosixThreadExt, time::timeval_t, util::write_val_to_user, +}; + +#[derive(Debug, Copy, Clone, TryFromInt, PartialEq)] +#[repr(i32)] +enum RusageTarget { + ForSelf = 0, + Children = -1, + Both = -2, + Thread = 1, +} + +pub fn sys_getrusage(target: i32, rusage_addr: Vaddr) -> Result { + let rusage_target = RusageTarget::try_from(target)?; + + debug!( + "target = {:?}, rusage_addr = {}", + rusage_target, rusage_addr, + ); + + if rusage_addr != 0 { + let rusage = match rusage_target { + RusageTarget::ForSelf => { + let process = current!(); + rusage_t { + ru_utime: process.prof_clock().user_clock().read_time().into(), + ru_stime: process.prof_clock().kernel_clock().read_time().into(), + ..Default::default() + } + } + RusageTarget::Thread => { + let thread = current_thread!(); + let posix_thread = thread.as_posix_thread().unwrap(); + rusage_t { + ru_utime: posix_thread.prof_clock().user_clock().read_time().into(), + ru_stime: posix_thread.prof_clock().kernel_clock().read_time().into(), + ..Default::default() + } + } + // To support `Children` and `Both` we need to implement the functionality to + // accumulate the resources of a child process back to the parent process + // upon the child's termination. + _ => { + return_errno_with_message!(Errno::EINVAL, "the target type is not supported") + } + }; + + write_val_to_user(rusage_addr, &rusage)?; + } + + Ok(SyscallReturn::Return(0)) +} + +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Pod)] +pub struct rusage_t { + /// user time used + pub ru_utime: timeval_t, + /// system time used + pub ru_stime: timeval_t, + /// maximum resident set size + pub ru_maxrss: u64, + /// integral shared memory size + pub ru_ixrss: u64, + /// integral unshared data size + pub ru_idrss: u64, + /// integral unshared stack size + pub ru_isrss: u64, + /// page reclaims + pub ru_minflt: u64, + /// page faults + pub ru_majflt: u64, + /// swaps + pub ru_nswap: u64, + /// block input operations + pub ru_inblock: u64, + /// block output operations + pub ru_oublock: u64, + /// messages sent + pub ru_msgsnd: u64, + /// messages received + pub ru_msgrcv: u64, + /// signals received + pub ru_nsignals: u64, + /// voluntary context switches + pub ru_nvcsw: u64, + /// involuntary + pub ru_nivcsw: u64, +} diff --git a/kernel/aster-nix/src/syscall/mod.rs b/kernel/aster-nix/src/syscall/mod.rs index ac199406a..36bfccd5e 100644 --- a/kernel/aster-nix/src/syscall/mod.rs +++ b/kernel/aster-nix/src/syscall/mod.rs @@ -48,6 +48,7 @@ mod getppid; mod getrandom; mod getresgid; mod getresuid; +mod getrusage; mod getsid; mod getsockname; mod getsockopt;