From 4668c7bcc6224a34822cfc6cbc4ea62593ea898b Mon Sep 17 00:00:00 2001 From: Richard Qin Date: Wed, 13 May 2026 16:26:58 +0800 Subject: feat: implement process control system calls (exit, getpid, gettid, sched_yield, wait4) --- na/kernel/sys_process.cc | 143 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 na/kernel/sys_process.cc (limited to 'na') diff --git a/na/kernel/sys_process.cc b/na/kernel/sys_process.cc new file mode 100644 index 0000000..1759a81 --- /dev/null +++ b/na/kernel/sys_process.cc @@ -0,0 +1,143 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* Copyright (C) 2026 Richard Qin */ + +/* + * Process Control System Calls + * + * Implements: exit, exit_group, getpid, gettid, getppid, + * sched_yield, clone (stub), wait4 (stub), + * set_tid_address, getuid, getgid. + * + * Reference: docs/specs/syscall.md ยง7.1 + */ + +#include +#include +#include +#include +#include +#include + +/* External: task lifecycle (kernel/task.cc) */ +extern void task_exit(int code); +extern void task_destroy(TaskControlBlock* task); +extern int32 task_wait(int32* exit_code); +extern int32 task_fork(arch::TrapFrame* tf); + +/* ====================================================================== + * sys_exit / sys_exit_group + * ====================================================================== */ + +int64 sys_exit(uint64 code, uint64, uint64, uint64, uint64, uint64) +{ + task_exit(static_cast(code & 0xFF)); + __builtin_unreachable(); +} + +int64 sys_exit_group(uint64 code, uint64, uint64, uint64, uint64, uint64) +{ + /* Phase 2: single-threaded, equivalent to sys_exit. + * Phase 3: kill all threads in tgid then exit. */ + task_exit(static_cast(code & 0xFF)); + __builtin_unreachable(); +} + +/* ====================================================================== + * sys_getpid / sys_gettid / sys_getppid + * ====================================================================== */ + +int64 sys_getpid(uint64, uint64, uint64, uint64, uint64, uint64) +{ + return current_task()->tgid; /* Linux: getpid() returns tgid */ +} + +int64 sys_gettid(uint64, uint64, uint64, uint64, uint64, uint64) +{ + return current_task()->pid; /* Linux: gettid() returns real tid */ +} + +int64 sys_getppid(uint64, uint64, uint64, uint64, uint64, uint64) +{ + TaskControlBlock* parent = current_task()->parent; + return parent ? parent->tgid : 0; +} + +/* ====================================================================== + * sys_sched_yield + * ====================================================================== */ + +int64 sys_sched_yield_wrapper(uint64, uint64, uint64, uint64, uint64, uint64) +{ + sched_yield(); + return 0; +} + +int64 sys_clone_wrapper(uint64 flags, uint64 child_stack, + uint64 ptid, uint64 ctid, uint64 tls, uint64) +{ + /* Phase A: Simple fork() support. + * Ignore flags/stack for now and just clone the current task. */ + (void)flags; (void)child_stack; (void)ptid; (void)ctid; (void)tls; + + arch::TrapFrame* tf = current_task()->trapframe; + if (!tf) return -EINVAL; + + return task_fork(tf); +} + +/* ======================================================================== + * sys_wait4 โ€” Wait for child to exit + * ======================================================================== */ + +int64 sys_wait4_wrapper(uint64 pid, uint64 wstatus_ptr, + uint64 options, uint64, uint64, uint64) +{ + /* Phase A: Basic wait() support. + * TODO: Implement pid-specific wait and WNOHANG in task_wait. */ + (void)pid; (void)options; + + int32 exit_code = 0; + int32 child_pid = task_wait(&exit_code); + + if (child_pid < 0) return child_pid; + + if (wstatus_ptr != 0) { + int wstatus = 0; + if (exit_code & kExitCodeSignalFlag) { + wstatus = exit_code & 0x7F; + } else { + wstatus = W_EXITCODE(exit_code); + } + if (copy_to_user(wstatus_ptr, &wstatus, sizeof(int)) < 0) + return -EFAULT; + } + + return child_pid; +} + +/* ====================================================================== + * sys_set_tid_address โ€” musl libc calls this very early + * ====================================================================== */ + +int64 sys_set_tid_address(uint64 tidptr, uint64, uint64, + uint64, uint64, uint64) +{ + /* Phase 2: store the clear_child_tid pointer (needed for futex wakeup). + * For now just return current tid. */ + (void)tidptr; + return current_task()->pid; +} + +/* ====================================================================== + * sys_getuid / sys_getgid โ€” Phase 2: always root + * ====================================================================== */ + +int64 sys_getuid(uint64, uint64, uint64, uint64, uint64, uint64) +{ + return 0; /* root */ +} + +int64 sys_getgid(uint64, uint64, uint64, uint64, uint64, uint64) +{ + return 0; /* root */ +} -- cgit v1.2.3