| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Bump PIPE_MAX to 4 so a|b|c|d|e (4 pipes) works. This stays within the
single-byte buffer-offset math (idx*64+pos <= 3*64+63 = 255) and the fd
space ($F0..$F7, clear of $FF console).
The bump exposed a data-corruption bug that also affected the 2-pipe case
(just invisibly - a wc-only test can't see mangled bytes): pipe_write kept
the byte-to-write in the SHARED wPipeByte global across its SchedYield
(buffer full), so a concurrent pipe op clobbered it and the writer then
stored the wrong byte. Now the byte is held in D across the yield, and
pipe_bufptr no longer clobbers D; pipe_read/pipe_write also push their idx
across SchedYield rather than assume the yield preserves registers.
Verified: count N | cat now streams EXACT content (no 'linn'/'llne'
corruption); count 60 | cat | cat | wc = 60 180 1671; 5-stage
count 4 | cat | cat | cat | cat prints line 1..4; SIGPIPE (count 200|true)
and count 100|wc still fine, no hangs.
|
|
|
Replace the shell's temp-file pipe hack with proper in-kernel FIFOs.
Kernel (src/pipe.asm, new):
- A small pool of bounded ring buffers (PIPE_MAX=2, 64 B each) with
writers/readers refcounts. Pipe fds are $F0+idx*2 (read) / +1 (write);
$FF stays "console".
- SYS_PIPE allocates one (writers=readers=1) and returns the read fd
(write = read+1). getb/putb/close dispatch pipe fds here; sys_exit drops
the refcounts held as PROC_STDIN/PROC_STDOUT.
- Blocking with SchedYield, which is the flow control: read blocks while
empty with a writer (EOF once writers hit 0), write blocks while full
with a reader, and if the last reader is gone the writer is killed
(SIGPIPE -> exit 141). Cooperative-scheduler friendly.
Shell (c/sh.c):
- run_pipeline(): split on '|', make a pipe between adjacent stages, and
fork ALL stages concurrently (no wait between), wiring stdin/stdout;
then wait for all. Per-stage >/< still honored; orphaned pipe ends are
closed on a lookup miss so EOF/EPIPE propagate.
- Drop the __pipe temp file and its 2 KB / serialized limits.
libc: pipe(). New c/ptest.c exercises the FIFO (write, read back, EOF).
Now works (old version couldn't): multi-stage a|b|c; streaming beyond 2 KB
(count 120 | wc = 3372 bytes through a 64 B buffer); early-exit SIGPIPE
(count 200 | true kills count instead of hanging/overflowing a file).
|