kernel: Add the getrusage() system call
This commit is contained in:
parent
1fa8aeecce
commit
01111442d3
@ -39,6 +39,7 @@ set(SOURCES
|
|||||||
src/sys/link.cpp
|
src/sys/link.cpp
|
||||||
src/sys/uname.cpp
|
src/sys/uname.cpp
|
||||||
src/sys/mount.cpp
|
src/sys/mount.cpp
|
||||||
|
src/sys/resource.cpp
|
||||||
src/fs/VFS.cpp
|
src/fs/VFS.cpp
|
||||||
src/fs/Pipe.cpp
|
src/fs/Pipe.cpp
|
||||||
src/fs/Mount.cpp
|
src/fs/Mount.cpp
|
||||||
|
@ -28,9 +28,9 @@ Result<u64> sys_pstat(Registers*, SyscallArgs args)
|
|||||||
proc.ps_egid = thread->auth.egid;
|
proc.ps_egid = thread->auth.egid;
|
||||||
proc.ps_state = (int)thread->state;
|
proc.ps_state = (int)thread->state;
|
||||||
proc.ps_flags = thread->is_kernel ? PS_FLAG_KRNL : 0;
|
proc.ps_flags = thread->is_kernel ? PS_FLAG_KRNL : 0;
|
||||||
set_timespec(proc.ps_time, thread->ticks);
|
set_timespec(proc.ps_time, thread->user_ticks_self + thread->kernel_ticks_self);
|
||||||
set_timespec(proc.ps_ktime, thread->ticks_in_kernel);
|
set_timespec(proc.ps_ktime, thread->kernel_ticks_self);
|
||||||
set_timespec(proc.ps_utime, thread->ticks_in_user);
|
set_timespec(proc.ps_utime, thread->kernel_ticks_children);
|
||||||
strlcpy(proc.ps_name, thread->name.chars(), sizeof(proc.ps_name));
|
strlcpy(proc.ps_name, thread->name.chars(), sizeof(proc.ps_name));
|
||||||
strlcpy(proc.ps_cwd, thread->current_directory_path.is_empty() ? "/" : thread->current_directory_path.chars(),
|
strlcpy(proc.ps_cwd, thread->current_directory_path.is_empty() ? "/" : thread->current_directory_path.chars(),
|
||||||
sizeof(proc.ps_cwd));
|
sizeof(proc.ps_cwd));
|
||||||
|
32
kernel/src/sys/resource.cpp
Normal file
32
kernel/src/sys/resource.cpp
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#include "memory/MemoryManager.h"
|
||||||
|
#include "sys/Syscall.h"
|
||||||
|
#include "thread/Scheduler.h"
|
||||||
|
#include <bits/rusage.h>
|
||||||
|
|
||||||
|
static void ticks_to_rusage(struct rusage* ru, u64 sticks, u64 uticks)
|
||||||
|
{
|
||||||
|
ru->ru_stime.tv_sec = sticks / 1000;
|
||||||
|
ru->ru_stime.tv_usec = (sticks % 1000) * 1000;
|
||||||
|
ru->ru_utime.tv_sec = uticks / 1000;
|
||||||
|
ru->ru_utime.tv_usec = (uticks % 1000) * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<u64> sys_getrusage(Registers*, SyscallArgs args)
|
||||||
|
{
|
||||||
|
int who = (int)args[0];
|
||||||
|
struct rusage* ru = (struct rusage*)args[1];
|
||||||
|
|
||||||
|
auto* current = Scheduler::current();
|
||||||
|
|
||||||
|
struct rusage kru;
|
||||||
|
switch (who)
|
||||||
|
{
|
||||||
|
case RUSAGE_SELF: ticks_to_rusage(&kru, current->kernel_ticks_self, current->user_ticks_self); break;
|
||||||
|
case RUSAGE_CHILDREN: ticks_to_rusage(&kru, current->kernel_ticks_children, current->user_ticks_children); break;
|
||||||
|
default: return err(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!MemoryManager::copy_to_user_typed(ru, &kru)) return err(EFAULT);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -50,6 +50,9 @@ Result<u64> sys_waitpid(Registers*, SyscallArgs args)
|
|||||||
int status = (int)thread->status;
|
int status = (int)thread->status;
|
||||||
u64 id = thread->id;
|
u64 id = thread->id;
|
||||||
|
|
||||||
|
current->user_ticks_children += thread->user_ticks_self;
|
||||||
|
current->kernel_ticks_children += thread->kernel_ticks_self;
|
||||||
|
|
||||||
thread->state = ThreadState::Dying;
|
thread->state = ThreadState::Dying;
|
||||||
Scheduler::signal_reap_thread();
|
Scheduler::signal_reap_thread();
|
||||||
|
|
||||||
|
@ -261,11 +261,9 @@ namespace Scheduler
|
|||||||
{
|
{
|
||||||
CPU::disable_interrupts();
|
CPU::disable_interrupts();
|
||||||
|
|
||||||
g_current->ticks++;
|
if (is_in_kernel(regs)) g_current->kernel_ticks_self++;
|
||||||
|
|
||||||
if (is_in_kernel(regs)) g_current->ticks_in_kernel++;
|
|
||||||
else
|
else
|
||||||
g_current->ticks_in_user++;
|
g_current->user_ticks_self++;
|
||||||
|
|
||||||
g_current->ticks_left--;
|
g_current->ticks_left--;
|
||||||
|
|
||||||
@ -342,11 +340,11 @@ namespace Scheduler
|
|||||||
|
|
||||||
for (const auto* thread : g_threads)
|
for (const auto* thread : g_threads)
|
||||||
{
|
{
|
||||||
kdbgln("%p %c [%-20s] %4zu, parent = (%-18p,%zu), state = %d, ticks: (t:%04zu,k:%04zu,u:%04zu), status = "
|
kdbgln("%p %c [%-20s] %4zu, parent = (%-18p,%zu), state = %d, ticks: (k:%04zu,u:%04zu), status = "
|
||||||
"%d, cwd = %s",
|
"%d, cwd = %s",
|
||||||
thread, thread->is_kernel ? 'k' : 'u', thread->name.chars(), thread->id, thread->parent,
|
thread, thread->is_kernel ? 'k' : 'u', thread->name.chars(), thread->id, thread->parent,
|
||||||
thread->parent ? thread->parent->id : 0, (int)thread->state, thread->ticks, thread->ticks_in_kernel,
|
thread->parent ? thread->parent->id : 0, (int)thread->state, thread->kernel_ticks_self,
|
||||||
thread->ticks_in_user, thread->status,
|
thread->user_ticks_self, thread->status,
|
||||||
thread->current_directory_path.is_empty() ? "/" : thread->current_directory_path.chars());
|
thread->current_directory_path.is_empty() ? "/" : thread->current_directory_path.chars());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,9 +59,10 @@ struct Thread : public LinkedListNode<Thread>
|
|||||||
|
|
||||||
Credentials auth;
|
Credentials auth;
|
||||||
|
|
||||||
u64 ticks = 0;
|
u64 user_ticks_self = 0;
|
||||||
u64 ticks_in_user = 0;
|
u64 kernel_ticks_self = 0;
|
||||||
u64 ticks_in_kernel = 0;
|
u64 user_ticks_children = 0;
|
||||||
|
u64 kernel_ticks_children = 0;
|
||||||
|
|
||||||
u64 ticks_left;
|
u64 ticks_left;
|
||||||
u64 sleep_ticks_left;
|
u64 sleep_ticks_left;
|
||||||
|
17
libc/include/bits/rusage.h
Normal file
17
libc/include/bits/rusage.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/* bits/rusage.h: The rusage structure. */
|
||||||
|
|
||||||
|
#ifndef _BITS_RUSAGE_H
|
||||||
|
#define _BITS_RUSAGE_H
|
||||||
|
|
||||||
|
#include <bits/timespec.h>
|
||||||
|
|
||||||
|
struct rusage
|
||||||
|
{
|
||||||
|
struct timeval ru_utime;
|
||||||
|
struct timeval ru_stime;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define RUSAGE_SELF 0
|
||||||
|
#define RUSAGE_CHILDREN 1
|
||||||
|
|
||||||
|
#endif
|
@ -5,7 +5,7 @@
|
|||||||
_e(lseek) _e(mkdir) _e(execve) _e(fork) _e(waitpid) _e(getppid) _e(fcntl) _e(getdents) _e(getuid) _e(geteuid) \
|
_e(lseek) _e(mkdir) _e(execve) _e(fork) _e(waitpid) _e(getppid) _e(fcntl) _e(getdents) _e(getuid) _e(geteuid) \
|
||||||
_e(getgid) _e(getegid) _e(setuid) _e(setgid) _e(seteuid) _e(setegid) _e(fchmodat) _e(fchownat) _e(ioctl) \
|
_e(getgid) _e(getegid) _e(setuid) _e(setgid) _e(seteuid) _e(setegid) _e(fchmodat) _e(fchownat) _e(ioctl) \
|
||||||
_e(fstatat) _e(chdir) _e(getcwd) _e(unlinkat) _e(uname) _e(sethostname) _e(dup2) _e(pipe) _e(mount) \
|
_e(fstatat) _e(chdir) _e(getcwd) _e(unlinkat) _e(uname) _e(sethostname) _e(dup2) _e(pipe) _e(mount) \
|
||||||
_e(umount) _e(pstat)
|
_e(umount) _e(pstat) _e(getrusage)
|
||||||
|
|
||||||
enum Syscalls
|
enum Syscalls
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user