From: Tulio A M Mendes Date: Thu, 12 Feb 2026 03:49:04 +0000 (-0300) Subject: feat: times() syscall (84) — per-process CPU time accounting (utime/stime fields... X-Git-Url: https://projects.tadryanom.me/docs/POSIX_ROADMAP.md?a=commitdiff_plain;h=5404ca282bfd01583db244250d11edf28018a646;p=AdrOS.git feat: times() syscall (84) — per-process CPU time accounting (utime/stime fields in struct process) --- diff --git a/include/process.h b/include/process.h index 70b0570..8c2ace6 100644 --- a/include/process.h +++ b/include/process.h @@ -58,6 +58,8 @@ struct process { process_state_t state; uint32_t wake_at_tick; uint32_t alarm_tick; + uint32_t utime; /* ticks spent in user mode */ + uint32_t stime; /* ticks spent in kernel mode */ int exit_status; int has_user_regs; diff --git a/include/syscall.h b/include/syscall.h index ff6680c..b53b86b 100644 --- a/include/syscall.h +++ b/include/syscall.h @@ -107,6 +107,7 @@ enum { SYSCALL_READV = 81, SYSCALL_WRITEV = 82, SYSCALL_ALARM = 83, + SYSCALL_TIMES = 84, }; #endif diff --git a/src/kernel/scheduler.c b/src/kernel/scheduler.c index f7cb152..b23e80c 100644 --- a/src/kernel/scheduler.c +++ b/src/kernel/scheduler.c @@ -836,6 +836,11 @@ void process_wake_check(uint32_t current_tick) { return; } + /* CPU time accounting: charge one tick to the running process */ + if (current_process && current_process->state == PROCESS_RUNNING) { + current_process->utime++; + } + struct process* start = iter; do { if (iter->state == PROCESS_SLEEPING) { diff --git a/src/kernel/syscall.c b/src/kernel/syscall.c index 2f7a9ad..ee9053a 100644 --- a/src/kernel/syscall.c +++ b/src/kernel/syscall.c @@ -2272,6 +2272,11 @@ void syscall_handler(struct registers* regs) { return; } + if (syscall_no == SYSCALL_TIMES) { + posix_ext_syscall_dispatch(regs, syscall_no); + return; + } + if (syscall_no == SYSCALL_ALARM) { if (!current_process) { regs->eax = 0; return; } uint32_t seconds = regs->ebx; @@ -2448,6 +2453,23 @@ static void posix_ext_syscall_dispatch(struct registers* regs, uint32_t syscall_ return; } + if (syscall_no == SYSCALL_TIMES) { + if (!current_process) { regs->eax = (uint32_t)-EINVAL; return; } + struct { uint32_t tms_utime; uint32_t tms_stime; uint32_t tms_cutime; uint32_t tms_cstime; } tms; + tms.tms_utime = current_process->utime; + tms.tms_stime = current_process->stime; + tms.tms_cutime = 0; + tms.tms_cstime = 0; + void* user_buf = (void*)regs->ebx; + if (user_buf) { + if (copy_to_user(user_buf, &tms, sizeof(tms)) < 0) { + regs->eax = (uint32_t)-EFAULT; return; + } + } + regs->eax = get_tick_count(); + return; + } + regs->eax = (uint32_t)-ENOSYS; } diff --git a/user/ulibc/include/sys/times.h b/user/ulibc/include/sys/times.h new file mode 100644 index 0000000..b8d3032 --- /dev/null +++ b/user/ulibc/include/sys/times.h @@ -0,0 +1,15 @@ +#ifndef ULIBC_SYS_TIMES_H +#define ULIBC_SYS_TIMES_H + +#include + +struct tms { + uint32_t tms_utime; + uint32_t tms_stime; + uint32_t tms_cutime; + uint32_t tms_cstime; +}; + +uint32_t times(struct tms* buf); + +#endif diff --git a/user/ulibc/include/syscall.h b/user/ulibc/include/syscall.h index 7501627..31cbe78 100644 --- a/user/ulibc/include/syscall.h +++ b/user/ulibc/include/syscall.h @@ -66,6 +66,7 @@ enum { SYS_READV = 81, SYS_WRITEV = 82, SYS_ALARM = 83, + SYS_TIMES = 84, }; /* Raw syscall wrappers — up to 5 args via INT 0x80 */ diff --git a/user/ulibc/src/times.c b/user/ulibc/src/times.c new file mode 100644 index 0000000..59476e7 --- /dev/null +++ b/user/ulibc/src/times.c @@ -0,0 +1,6 @@ +#include "sys/times.h" +#include "syscall.h" + +uint32_t times(struct tms* buf) { + return (uint32_t)_syscall1(SYS_TIMES, (int)buf); +}