aboutsummaryrefslogtreecommitdiffstats
path: root/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'README.md')
-rw-r--r--README.md28
1 files changed, 26 insertions, 2 deletions
diff --git a/README.md b/README.md
index 3f6aab0..929cafe 100644
--- a/README.md
+++ b/README.md
@@ -45,13 +45,35 @@ User loads `C` = syscall number, args in `DE`/`B`, then `rst $30`. Return in `A`
| # | name | status |
|---|---------|--------|
-| 0 | exit | ✅ marks zombie, reschedules |
+| 0 | exit | ✅ zombie + reparent orphans + wake waiter |
| 1 | fork | ✅ copies the 8 KiB bank, child returns 0 |
| 3 | write | ✅ `DE`=buf `B`=len → serial console |
| 6 | exec | ✅ `B`=program id → maps ROM text bank, jumps in |
+| 7 | wait | ✅ blocks; reaps a zombie child → `A`=pid `B`=code |
| 8 | getpid | ✅ |
| 11| yield | ✅ cooperative switch |
-| 2,4,5,7,9,10 | read/open/close/wait/kill/brk | ⛔ `ENOSYS` |
+| 2,4,5,9,10 | read/open/close/kill/brk | ⛔ `ENOSYS` |
+
+### Process lifecycle (exit / wait / reaping)
+
+The classic Unix zombie/reap dance, adapted to banked memory:
+
+- **`exit(code)`** sets `PS_ZOMBIE` + status, **reparents** any children to init
+ (pid 1), **wakes** the parent if it's blocked in `wait()`, then schedules
+ away forever. Its resources are freed by the reaper, not here.
+- **`wait()`** scans for a `PS_ZOMBIE` child. Found → **reap**: free its
+ cart-RAM bank (back to the allocator) and its PCB slot, return pid + code.
+ Children exist but none dead → set self `PS_BLOCKED` and yield, retry on wake.
+ No children → return `$FF` (`ECHILD`).
+- The scheduler skips non-`READY` procs; `FindNextReady` returns carry when
+ nothing is runnable so `yield` just keeps the caller running (idle).
+- **Cart-RAM banks are a free list** (`wBankUsed` bitmap): `AllocRamBank` /
+ `FreeRamBank`. Verified by running 6 workers through only 3 child banks
+ (`w2w3w4w5w6w7`) — each reaped bank is recycled by the next `fork`.
+
+Lifecycle demo (`tasks.asm`): init forks 3 workers, each `exec`s PROG_WORKER
+(prints `w`, exits with its pid), init `wait`s and reaps all three →
+`wwwR2R3R4!`.
### exec (`sys_exec`, src/proc.asm + programs.asm)
@@ -131,7 +153,9 @@ A real gbos would render to VRAM; serial is the zero-VRAM debug channel.
- [x] `fork`: copy parent's 8 KiB RAM bank → free bank, child returns 0
- [x] `exec`: point `PROC_ROMB` at a program in a ROM bank, reset stack, enter
+- [x] `exit` / `wait` / zombie reaping + cart-RAM bank recycling (free list)
- [ ] `exec` refinement: copy `.data` from ROM + zero `.bss` for RW globals
+- [ ] a real shell program: `fork`+`exec`+`wait` driven from the serial console
- [ ] Preemptive scheduling: real context save in `TimerISR` → `hSwitchTo`
- [ ] Use the `$D000-$DFFF` u-area (SVBK) for per-process kernel state / kstack
- [ ] `brk`/heap allocator inside the task bank (heap up, stack down, collision = ENOMEM)