Kernel: Add the clock_gettime syscall, which replaces clock as it can be used for more stuff

This commit is contained in:
apio 2022-10-30 09:07:59 +01:00
parent baf97840e9
commit 688a640a16
3 changed files with 60 additions and 3 deletions

View File

@ -18,7 +18,7 @@
#define SYS_execv 12 #define SYS_execv 12
#define SYS_fcntl 13 #define SYS_fcntl 13
#define SYS_mprotect 14 #define SYS_mprotect 14
#define SYS_clock 15 #define SYS_clock_gettime 15
#define SYS_mkdir 16 #define SYS_mkdir 16
#define SYS_fork 17 #define SYS_fork 17
#define SYS_waitpid 18 #define SYS_waitpid 18
@ -34,6 +34,7 @@
struct stat; struct stat;
struct pstat; struct pstat;
struct luna_dirent; struct luna_dirent;
struct timespec;
namespace Syscall 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_execv(Context* context, const char* pathname, char** argv);
void sys_fcntl(Context* context, int fd, int command, uintptr_t arg); 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_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_mkdir(Context* context, const char* filename, mode_t mode);
void sys_fork(Context* context); void sys_fork(Context* context);
void sys_waitpid(Context* context, long pid, int* wstatus, int options); void sys_waitpid(Context* context, long pid, int* wstatus, int options);

View File

@ -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_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_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_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_mkdir: sys_mkdir(context, (const char*)context->rdi, (mode_t)context->rsi); break;
case SYS_fork: sys_fork(context); break; case SYS_fork: sys_fork(context); break;
case SYS_waitpid: sys_waitpid(context, (long)context->rdi, (int*)context->rsi, (int)context->rdx); break; case SYS_waitpid: sys_waitpid(context, (long)context->rdi, (int*)context->rsi, (int)context->rdx); break;

View File

@ -9,6 +9,62 @@
static uint64_t unix_boot_time; 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; extern BOOTBOOT bootboot;
void clock_init() void clock_init()