mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-11 05:25:32 +03:00
Implement basic support for times().
The kernel now bills processes for time spent in kernelspace and userspace separately. The accounting is forwarded to the parent process in reap(). This makes the "time" builtin in bash work.
This commit is contained in:
parent
4bc87dc7b9
commit
e7cc08226f
Notes:
sideshowbarker
2024-07-19 16:09:02 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/e7cc08226f5
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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; }
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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))
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <Kernel/Syscall.h>
|
||||
#include <AK/printf.cpp>
|
||||
|
||||
extern "C" {
|
||||
|
@ -5,8 +5,8 @@
|
||||
#include <string.h>
|
||||
#include <alloca.h>
|
||||
#include <assert.h>
|
||||
#include <Kernel/Syscall.h>
|
||||
#include <AK/Assertions.h>
|
||||
#include <AK/Types.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
#include <sys/times.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <Kernel/Syscall.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user