From 688a640a16edb3b14cb1b7cf434068ad652ab7f9 Mon Sep 17 00:00:00 2001 From: apio Date: Sun, 30 Oct 2022 09:07:59 +0100 Subject: [PATCH] Kernel: Add the clock_gettime syscall, which replaces clock as it can be used for more stuff --- kernel/include/sys/Syscall.h | 5 ++-- kernel/src/sys/Syscall.cpp | 2 +- kernel/src/sys/clock.cpp | 56 ++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/kernel/include/sys/Syscall.h b/kernel/include/sys/Syscall.h index 036eba79..d09e6ddc 100644 --- a/kernel/include/sys/Syscall.h +++ b/kernel/include/sys/Syscall.h @@ -18,7 +18,7 @@ #define SYS_execv 12 #define SYS_fcntl 13 #define SYS_mprotect 14 -#define SYS_clock 15 +#define SYS_clock_gettime 15 #define SYS_mkdir 16 #define SYS_fork 17 #define SYS_waitpid 18 @@ -34,6 +34,7 @@ struct stat; struct pstat; struct luna_dirent; +struct timespec; namespace Syscall { @@ -55,7 +56,7 @@ void sys_seek(Context* context, int fd, long offset, int whence); void sys_execv(Context* context, const char* pathname, char** argv); void sys_fcntl(Context* context, int fd, int command, uintptr_t arg); void sys_mprotect(Context* context, void* address, size_t size, int prot); -void sys_clock(Context* context); +void sys_clock_gettime(Context* context, int clock_id, struct timespec* tp); void sys_mkdir(Context* context, const char* filename, mode_t mode); void sys_fork(Context* context); void sys_waitpid(Context* context, long pid, int* wstatus, int options); diff --git a/kernel/src/sys/Syscall.cpp b/kernel/src/sys/Syscall.cpp index 0378acb9..357ab199 100644 --- a/kernel/src/sys/Syscall.cpp +++ b/kernel/src/sys/Syscall.cpp @@ -26,7 +26,7 @@ void Syscall::entry(Context* context) case SYS_execv: sys_execv(context, (const char*)context->rdi, (char**)context->rsi); break; case SYS_fcntl: sys_fcntl(context, (int)context->rdi, (int)context->rsi, context->rdx); break; case SYS_mprotect: sys_mprotect(context, (void*)context->rdi, context->rsi, (int)context->rdx); break; - case SYS_clock: sys_clock(context); break; + case SYS_clock_gettime: sys_clock_gettime(context, (int)context->rdi, (struct timespec*)context->rsi); break; case SYS_mkdir: sys_mkdir(context, (const char*)context->rdi, (mode_t)context->rsi); break; case SYS_fork: sys_fork(context); break; case SYS_waitpid: sys_waitpid(context, (long)context->rdi, (int*)context->rsi, (int)context->rdx); break; diff --git a/kernel/src/sys/clock.cpp b/kernel/src/sys/clock.cpp index 364fd494..99374f32 100644 --- a/kernel/src/sys/clock.cpp +++ b/kernel/src/sys/clock.cpp @@ -9,6 +9,62 @@ static uint64_t unix_boot_time; +#define CLOCK_REALTIME 0 +#define CLOCK_MONOTONIC 1 +#define CLOCK_PROCTIME 2 + +struct timeval +{ + time_t tv_sec; + suseconds_t tv_usec; +}; + +struct timespec +{ + time_t tv_sec; + long tv_nsec; +}; + +static void ms_to_timespec(long ms, struct timespec* tv) +{ + tv->tv_sec = ms / 1000; + tv->tv_nsec = (ms % 1000) * 1000000; +} + +void sys_clock_gettime(Context* context, int clock, struct timespec* tp) +{ + struct timespec* ktp = obtain_user_ref(tp); + if (!ktp) + { + context->rax = -EFAULT; // FIXME: Not sure if clock_gettime can return EFAULT. + return; + } + Task* current_task = Scheduler::current_task(); + switch (clock) + { + case CLOCK_REALTIME: { + ms_to_timespec(PIT::ms_since_boot, ktp); + ktp->tv_sec += unix_boot_time; + break; + } + case CLOCK_MONOTONIC: { + ms_to_timespec(PIT::ms_since_boot, ktp); + break; + } + case CLOCK_PROCTIME: { + ms_to_timespec(current_task->cpu_time, ktp); + break; + } + default: + release_user_ref(ktp); + context->rax = -EINVAL; + return; + } + release_user_ref(ktp); + context->rax = 0; + return; +} + extern BOOTBOOT bootboot; void clock_init()