]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
feat: times() syscall (84) — per-process CPU time accounting (utime/stime fields...
authorTulio A M Mendes <[email protected]>
Thu, 12 Feb 2026 03:49:04 +0000 (00:49 -0300)
committerTulio A M Mendes <[email protected]>
Fri, 13 Feb 2026 02:20:50 +0000 (23:20 -0300)
include/process.h
include/syscall.h
src/kernel/scheduler.c
src/kernel/syscall.c
user/ulibc/include/sys/times.h [new file with mode: 0644]
user/ulibc/include/syscall.h
user/ulibc/src/times.c [new file with mode: 0644]

index 70b0570bf42022c9dac6a71a282c80d0b45153e2..8c2ace63720a2304837e233b45c125e1d0167128 100644 (file)
@@ -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;
index ff6680c4771e4b421f9f0f3120143db883c66da2..b53b86be0f604711fb4941e8f7c4003b264ae922 100644 (file)
@@ -107,6 +107,7 @@ enum {
     SYSCALL_READV     = 81,
     SYSCALL_WRITEV    = 82,
     SYSCALL_ALARM     = 83,
+    SYSCALL_TIMES     = 84,
 };
 
 #endif
index f7cb152db0f96fccfcb51ed52fe3ec2fd2b725a3..b23e80c961a966496e061d62fcc244af6b446462 100644 (file)
@@ -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) {
index 2f7a9ad33cfcf99747f6f649ee994d4fb576437c..ee9053ae88e12f24bcdda5e873db1aa87e49e70b 100644 (file)
@@ -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 (file)
index 0000000..b8d3032
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef ULIBC_SYS_TIMES_H
+#define ULIBC_SYS_TIMES_H
+
+#include <stdint.h>
+
+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
index 7501627cebf0f2e09a4d4bbeaf5cc9dfba130c11..31cbe78ac2f399cbf5d0156132826191d7e8a824 100644 (file)
@@ -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 (file)
index 0000000..59476e7
--- /dev/null
@@ -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);
+}