-
Notifications
You must be signed in to change notification settings - Fork 63
Process Management
A guided, code-backed overview of process management in MentOS.
A process is the unit of execution in MentOS. It owns:
- A virtual address space (its
mm_struct_t) - A stack and registers (
thread_struct_t) - Open file descriptors
- Identity and group information (PID/PPID/PGID/SID, UID/GID)
- Scheduling metadata
From user space, you interact with processes mainly through the POSIX-style APIs in unistd.h and sys/wait.h.
The kernel creates the init process at boot and loads /bin/init. It also wires standard I/O to /proc/video so user programs can read and write to the screen and keyboard:
- The init process is created in
process_create_init(). - STDIN/STDOUT/STDERR are attached to
/proc/video.
Relevant code paths:
- kernel/src/process/process.c
- kernel/inc/process/process.h
fork() creates a new process by cloning the current process state and address space. In MentOS:
- The child gets a cloned memory map (
mm_clone). - File descriptors are duplicated (
vfs_dup_task). - The child sees a return value of 0.
- The parent receives the child PID.
User-side API:
#include <unistd.h>
pid_t pid = fork();
if (pid == 0) {
// child
} else if (pid > 0) {
// parent
}execve() replaces the current process image with a new executable. In MentOS:
- The old address space is destroyed and rebuilt (
mm_destroy,mm_create_blank). - ELF binaries are loaded by the kernel ELF loader.
- Shebang (
#!) scripts are supported. - A NULL
envpis accepted and replaced with a default environment:PATH=/bin:/usr/binHOME=/
User-side API:
#include <unistd.h>
char *argv[] = {"/bin/echo", "hello", NULL};
char *envp[] = {"PATH=/bin:/usr/bin", "HOME=/", NULL};
execve(argv[0], argv, envp);exit() marks a process as a zombie and notifies the parent with SIGCHLD. The parent should collect the exit status with waitpid().
User-side API:
#include <sys/wait.h>
#include <unistd.h>
pid_t pid = fork();
if (pid == 0) {
// child
_exit(42);
}
int status = 0;
pid_t done = waitpid(pid, &status, 0);
if (done > 0 && WIFEXITED(status)) {
int code = WEXITSTATUS(status);
}MentOS tracks the usual UNIX identifiers:
- PID: process ID
- PPID: parent process ID
- PGID: process group ID
- SID: session ID
- UID/GID: user and group IDs (real and effective)
User-side APIs (subset):
#include <unistd.h>
pid_t pid = getpid();
pid_t ppid = getppid();
pid_t pgid = getpgid(0);
pid_t sid = getsid(0);
setpgid(0, pgid);
setsid();Notes about waitpid() in MentOS:
-
pid == -1(any child) andpid > 0(specific child) are supported. -
pid == 0orpid < -1are not supported. - Only
WNOHANGandWUNTRACEDare accepted; other options return-EINVAL.
Processes are scheduled from a run queue (runqueue_t) and can be in these states:
TASK_RUNNINGTASK_INTERRUPTIBLETASK_UNINTERRUPTIBLETASK_STOPPEDTASK_TRACEDEXIT_ZOMBIEEXIT_DEAD
MentOS supports multiple scheduling algorithms (configured at build time). See Scheduling for a full overview.
Processes can receive POSIX-like signals. When a process exits, the kernel sends SIGCHLD to the parent.
User-side APIs are defined in <signal.h> and <sys/wait.h> (for exit status macros). See IPC and System Calls for details.
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main(void)
{
pid_t pid = fork();
if (pid == 0) {
printf("child pid=%d\n", getpid());
_exit(0);
}
int status = 0;
waitpid(pid, &status, 0);
printf("parent saw child exit\n");
return 0;
}#include <unistd.h>
int main(void)
{
pid_t pid = fork();
if (pid == 0) {
char *argv[] = {"/bin/ls", "/", NULL};
execve(argv[0], argv, NULL); // NULL envp is allowed in MentOS
_exit(127);
}
waitpid(pid, NULL, 0);
return 0;
}-
task_structdescribes a process (IDs, state, file descriptors, memory, signals) -
thread_structstores register state -
sched_entitystores scheduling metadata
- Process creation and exec: kernel/src/process/process.c
- Scheduler and syscalls like
getpid,setpgid,waitpid,exit: kernel/src/process/scheduler.c - Wait queues and sleep primitives: kernel/src/process/wait.c
-
fork()usesmm_clone()and duplicates the parent file table. -
execve()enforces executable permission and supports shebangs. -
sys_exit()shifts the exit code by 8 bits before storing it (mirrors UNIX wait status encoding). - Exiting processes become zombies until the parent calls
waitpid().