diff --git a/AK/Types.h b/AK/Types.h index 2854fabaa34..bfba6136b87 100644 --- a/AK/Types.h +++ b/AK/Types.h @@ -12,7 +12,7 @@ typedef signed int signed_dword; typedef signed long long int signed_qword; typedef decltype(sizeof(void*)) size_t; -typedef long ssize_t; +typedef signed_dword ssize_t; static_assert(sizeof(size_t) == sizeof(dword)); static_assert(sizeof(ssize_t) == sizeof(signed_dword)); diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index c47aaf5defa..3a1db69a26c 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -1415,6 +1415,14 @@ int Process::reap(Process& process) { InterruptDisabler disabler; int exit_status = (process.m_termination_status << 8) | process.m_termination_signal; + + if (process.ppid()) { + auto* parent = Process::from_pid(process.ppid()); + ASSERT(parent); + parent->m_ticks_in_user_for_dead_children += process.m_ticks_in_user + process.m_ticks_in_user_for_dead_children; + parent->m_ticks_in_kernel_for_dead_children += process.m_ticks_in_kernel + process.m_ticks_in_kernel_for_dead_children; + } + dbgprintf("reap: %s(%u) {%s}\n", process.name().characters(), process.pid(), toString(process.state())); ASSERT(process.state() == Dead); g_processes->remove(&process); @@ -1763,3 +1771,14 @@ int Process::sys$mkdir(const char* pathname, mode_t mode) return error; return 0; } + +Unix::clock_t Process::sys$times(Unix::tms* times) +{ + if (!validate_write_typed(times)) + return -EFAULT; + times->tms_utime = m_ticks_in_user; + times->tms_stime = m_ticks_in_kernel; + times->tms_cutime = m_ticks_in_user_for_dead_children; + times->tms_cstime = m_ticks_in_kernel_for_dead_children; + return 0; +} diff --git a/Kernel/Process.h b/Kernel/Process.h index 56c829d7dda..5b56e320393 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -172,6 +172,7 @@ public: int sys$fcntl(int fd, int cmd, dword extra_arg); int sys$ioctl(int fd, unsigned request, unsigned arg); int sys$mkdir(const char* pathname, mode_t mode); + Unix::clock_t sys$times(Unix::tms*); static void initialize(); @@ -187,6 +188,12 @@ public: void did_schedule() { ++m_timesScheduled; } dword timesScheduled() const { return m_timesScheduled; } + dword m_ticks_in_user { 0 }; + dword m_ticks_in_kernel { 0 }; + + dword m_ticks_in_user_for_dead_children { 0 }; + dword m_ticks_in_kernel_for_dead_children { 0 }; + pid_t waitee_pid() const { return m_waitee_pid; } dword framePtr() const { return m_tss.ebp; } diff --git a/Kernel/Scheduler.cpp b/Kernel/Scheduler.cpp index 56fe2ddf7fc..88156eb9bbc 100644 --- a/Kernel/Scheduler.cpp +++ b/Kernel/Scheduler.cpp @@ -181,6 +181,12 @@ bool Scheduler::context_switch(Process& process) process.set_ticks_left(time_slice); process.did_schedule(); + if (process.tss().cs & 3) { + ++process.m_ticks_in_user; + } else { + ++process.m_ticks_in_kernel; + } + if (current == &process) return false; diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index 6a4711191f2..d5864406c86 100644 --- a/Kernel/Syscall.cpp +++ b/Kernel/Syscall.cpp @@ -175,6 +175,8 @@ static dword handle(RegisterDump& regs, dword function, dword arg1, dword arg2, return current->sys$fstat((int)arg1, (Unix::stat*)arg2); case Syscall::SC_mkdir: return current->sys$mkdir((const char*)arg1, (mode_t)arg2); + case Syscall::SC_times: + return current->sys$times((Unix::tms*)arg1); default: kprintf("<%u> int0x80: Unknown function %u requested {%x, %x, %x}\n", current->pid(), function, arg1, arg2, arg3); break; diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h index 18fdf5d9d79..81717dbda6b 100644 --- a/Kernel/Syscall.h +++ b/Kernel/Syscall.h @@ -63,6 +63,7 @@ __ENUMERATE_SYSCALL(fcntl) \ __ENUMERATE_SYSCALL(ioctl) \ __ENUMERATE_SYSCALL(mkdir) \ + __ENUMERATE_SYSCALL(times) \ #define DO_SYSCALL_A0(function) Syscall::invoke((dword)(function)) diff --git a/LibC/stdio.cpp b/LibC/stdio.cpp index ed49a3ee1f5..23223ca035b 100644 --- a/LibC/stdio.cpp +++ b/LibC/stdio.cpp @@ -8,7 +8,6 @@ #include #include #include -#include #include extern "C" { diff --git a/LibC/stdlib.cpp b/LibC/stdlib.cpp index fb5c737b050..1cb16f5a2f5 100644 --- a/LibC/stdlib.cpp +++ b/LibC/stdlib.cpp @@ -5,8 +5,8 @@ #include #include #include -#include #include +#include extern "C" { diff --git a/LibC/times.cpp b/LibC/times.cpp index a517e4385ef..0fe57c1a9ea 100644 --- a/LibC/times.cpp +++ b/LibC/times.cpp @@ -1,8 +1,9 @@ #include -#include +#include +#include -clock_t times(struct tms*) +clock_t times(struct tms* buf) { - assert(false); - return 0; + int rc = Syscall::invoke(Syscall::SC_times, (dword)buf); + __RETURN_WITH_ERRNO(rc, rc, (clock_t)-1); } diff --git a/VirtualFileSystem/UnixTypes.h b/VirtualFileSystem/UnixTypes.h index d1e0e36efb3..f90e860847b 100644 --- a/VirtualFileSystem/UnixTypes.h +++ b/VirtualFileSystem/UnixTypes.h @@ -219,6 +219,14 @@ typedef dword mode_t; typedef dword nlink_t; typedef dword uid_t; typedef dword gid_t; +typedef dword clock_t; + +struct tms { + clock_t tms_utime; + clock_t tms_stime; + clock_t tms_cutime; + clock_t tms_cstime; +}; #ifdef SERENITY typedef void (*__sighandler_t)(int);