diff options
| author | user <user@clank> | 2026-09-22 17:12:32 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-09-22 17:12:32 +0200 |
| commit | bb55479e693a04df0da8320adfa10a6b8188b8da (patch) | |
| tree | 9b3736cff55112982d1722bc4c1a9630785aeda9 /src/programs.asm | |
| parent | fs: bounds-check direct blocks - a file over 2 KiB ate the next inode (diff) | |
| download | gbos-bb55479e693a04df0da8320adfa10a6b8188b8da.tar.gz gbos-bb55479e693a04df0da8320adfa10a6b8188b8da.tar.xz gbos-bb55479e693a04df0da8320adfa10a6b8188b8da.zip | |
kernel: per-process sleep - two sleepers used to deadlock each other
sys_sleep kept its entire state in three globals (wSleepTarget, wSleepAcc,
wSleepLastDiv) and yielded inside its own loop. With two processes sleeping
at once, each zeroed the other's accumulator on entry, so neither ever
reached its target: both slept ~forever.
Nothing hit it while only one program at a time paced itself. `httpd &`
(polling accept) plus a foreground `ping` is enough: ping wedged with its
echo reply already sitting in the socket buffer, unread.
Now the deadline lives in registers - i.e. on the caller's own stack across
SchedYield, which makes it per-process by construction - and it counts the
64 Hz tick (wTicks, via TimerISR) instead of accumulating DIV deltas.
ticks16 re-reads the counter until the high byte is stable, so a carry
between the two byte reads can't report a 256-unit jump.
Diffstat (limited to 'src/programs.asm')
0 files changed, 0 insertions, 0 deletions
