proc.mgr¶
Preemptive process manager providing process creation, scheduling, messaging, resource binding, and reaping.
Overview¶
proc.mgr is the core process management unit for the Asuro kernel. It maintains a doubly-linked list (PDList) of PProcessContext pointers and implements:
- Process creation — allocates a
TProcessContext, builds a fake interrupt frame on a newly-allocated 8 KiB stack so the first context switchIRETs intoprocess_trampoline, and marks the process aspsReady. - Round-robin scheduler —
scheduler_pick_nextis called from the context-switch ISR. It reaps finished processes, checks the current process's remaining quantum, and scans the process list for the nextpsReadyprocess. Falls back to the idle process if none is found. - System messaging —
sendMessagewrites aTProcessSysMsginto the target process'sPendingMsgfield and wakes awaiting or suspended processes as appropriate. - Resource binding —
bindResource/unbindResource/unbindAllResourcesmanage a per-process list ofTResourceBindingrecords, each carrying a handle and aTResourceCleanupcallback invoked on unbind or reap. - Legacy command wrapper —
runCommandwraps aTCommandMethodas a process by routing throughlegacy_entry, enabling terminal commands to run as proper preemptive processes.
A dedicated idle process (PID 0, name 'Idle') is created at init time. It runs on the kernel's original stack, is never reaped, and is selected by the scheduler whenever no other process is runnable.
Three shell commands are exposed: PS (process list), KILL (immediate state transition to psFinished), and TERMINATE (graceful smTerminate message).
Dependencies¶
arch.x86.bdadriver.storage.fdtablecore.ds.listsmemory.heapproc.typescore.randio.stdio,io.syslogcore.strings,core.util,arch.x86.utildebug.tracer
Variables¶
| Variable | Type | Description |
|---|---|---|
CurrentProcess |
PProcessContext |
The process currently executing; never nil — at minimum the idle process. |
IdleProcess |
PProcessContext |
PID 0 idle process. Unkillable; runs the kernel's original HLT loop. |
Processes |
PDList |
Process table containing uint32-sized slots, each holding a PProcessContext. |
SchedulerIndex |
uint32 |
Round-robin cursor into the process list. |
Functions and Procedures¶
init¶
Creates the process table DList, allocates and initializes the idle process (PID 0, priority 0, quantum 1), sets CurrentProcess to the idle process, and registers the PS, KILL, and TERMINATE shell commands.
create¶
function create(name: pchar;
entry: TProcessEntryPoint;
localData: void;
priority: uint8): PProcessContext;
Allocates and fully initializes a new process context. Assigns a random PID via rand32, copies name (truncated to 31 characters), allocates an 8 KiB kernel stack, and builds the initial stack frame:
- 3-word IRET frame: EFLAGS (
$0202, IF=1), CS ($08), EIP →process_trampoline. - 8-register POPAD frame (all zero).
- 4 segment registers pushed as 32-bit values: DS, ES, FS, GS =
$10.
SavedESP is set to the bottom of this frame. localData is stored in ctx^.Local. A PDList resource list and a per-process FD table are allocated. The working directory is initialized to '/'. The context is appended to Processes and transitioned to psReady.
findByID / findByName¶
Linear search through the process table. findByName uses stringEquals (case-sensitive). Both return nil if not found.
sendMessage¶
Sets PendingMsg and MsgData on the target process. If the process is psAwaiting, transitions it to psReady. If suspended and receiving smResume, transitions it to psReady.
terminate¶
Sends smTerminate to the process. The process is responsible for checking PendingMsg and exiting gracefully. PID 0 is silently ignored.
kill¶
Directly sets the process state to psFinished with exit code $FFFFFFFF. The process is reaped on the next scheduler cycle. PID 0 is silently ignored.
proc_yield¶
Forces preemption by setting TicksUsed := Quantum then halting with HLT. The next timer interrupt will reschedule.
proc_sleep_ms¶
Yields repeatedly until approximately ms milliseconds have elapsed, measured by comparing the BDA 1024 Hz tick counter with overflow handling.
proc_await¶
Busy-waits on HLT while CurrentProcess^.State = psAwaiting. The caller must set psAwaiting before calling. An ISR or another process must set the state to something other than psAwaiting to unblock.
proc_suspend¶
Sets CurrentProcess^.State := psSuspended and halts. The process does not execute again until smResume is delivered via sendMessage.
proc_exit¶
Sets the exit code, transitions the process to psFinished, and enters an infinite HLT loop awaiting reaping.
bindResource / unbindResource / unbindResourceNoCleanup / unbindAllResources¶
procedure bindResource(ctx: PProcessContext; kind: TResourceKind; handle: void; cleanup: TResourceCleanup);
procedure unbindResource(ctx: PProcessContext; handle: void);
procedure unbindResourceNoCleanup(ctx: PProcessContext; handle: void);
procedure unbindAllResources(ctx: PProcessContext);
Manage per-process resource bindings. bindResource appends a TResourceBinding to the process's resource DList. unbindResource calls the cleanup callback before removing the binding. unbindResourceNoCleanup removes without calling cleanup. unbindAllResources detaches the DList, iterates in reverse calling all cleanup callbacks, then frees the list.
runCommand¶
function runCommand(name: pchar; method: TCommandMethod; params: PParamList;
stdin_buf, stdout_buf, stderr_buf: POutBuf): PProcessContext;
Creates a priority-1 process with legacy_entry as the entry point, storing method in Local and params in MsgData. Attaches the provided I/O buffers. Returns the new context, or nil if creation fails.
processCount / getProcessByIndex¶
Query the process table size and retrieve a context by table index.
scheduler_pick_next¶
Called from the context-switch ISR. Steps:
- Calls
reapFinishedto free terminated processes. - If
CurrentProcessis still running and has remaining quantum, returns it. - Transitions the current process from
psRunningtopsReadyand resetsTicksUsed. - Scans from
SchedulerIndexin round-robin order, skipping PID 0 and non-ready processes. - Returns the first
psReadyprocess found, orIdleProcessif none.
reapFinished¶
Iterates the process table in reverse (to handle index shifting safely). For each process in psFinished or psError state (excluding CurrentProcess and PID 0): notifies the parent via smChildExited, frees the FD table, frees the working directory, calls unbindAllResources, frees the stack, removes the slot from the DList, and frees the context.
terminal_command_ps¶
Prints a formatted table of all processes: PID (hex), name, state, and priority.
terminal_command_kill / terminal_command_terminate¶
procedure terminal_command_kill(params: PParamList; stdin_buf, stdout_buf, stderr_buf: POutBuf);
procedure terminal_command_terminate(params: PParamList; stdin_buf, stdout_buf, stderr_buf: POutBuf);
Shell commands accepting a hex PID argument. KILL calls kill; TERMINATE calls terminate.
Notes¶
The fake stack frame built by create uses the process_trampoline procedure as the EIP target. On the first IRET, the trampoline calls CurrentProcess^.EntryPoint(CurrentProcess). When the entry point returns, the trampoline sets psFinished and halts, waiting for reapFinished to reclaim the context.
unbindAllResources detaches ctx^.Resources to nil before iterating, so cleanup callbacks that call back into the resource system will see an empty list and not cause double-frees.
Process IDs are generated by core.rand.rand32 and are not guaranteed to be unique, though collisions are unlikely in practice. PID 0 is reserved for the idle process and bypasses kill/terminate guards.