feat: extend kmain with stderrDriverThread
This commit is contained in:
1 parent
04d722667e
commit
d621db9147
1 file changed
+173
+173
@@ -1196,6 +1196,179 @@ static void hereStringPipelineDriverThread(void)
|
|||||||
* "stderrwriter 2>> /tmp/stderr.txt" (append, same path) leaves a real
|
* "stderrwriter 2>> /tmp/stderr.txt" (append, same path) leaves a real
|
||||||
* tmpfs file holding two back-to-back copies of stderrwriter.c's own
|
* tmpfs file holding two back-to-back copies of stderrwriter.c's own
|
||||||
* payload; "stderrreader < /tmp/stderr.txt" then reads that file back
|
* payload; "stderrreader < /tmp/stderr.txt" then reads that file back
|
||||||
|
* through a REAL redirected stdin and compares it byte-for-byte against
|
||||||
|
* exactly that doubled payload. The actual pass/fail proof is entirely
|
||||||
|
* stderrreader.c's own doing (its "payload-ok" needle only prints on an
|
||||||
|
* exact match) -- this thread's only job is to type the three commands and
|
||||||
|
* give the scheduler real time between them.
|
||||||
|
*/
|
||||||
|
static void stderrDriverThread(void)
|
||||||
|
{
|
||||||
|
threadSleep(stderrDriverInitialDelayMs);
|
||||||
|
while (currentThread()->state == threadSleeping)
|
||||||
|
halt();
|
||||||
|
|
||||||
|
kprintf("[kbd] typing shell commands for the stderr redirection demo\n");
|
||||||
|
jobctlTypeFlushLine();
|
||||||
|
|
||||||
|
stderrTypeWriteTruncateCommand();
|
||||||
|
threadSleep(stderrDriverStepSettleMs);
|
||||||
|
while (currentThread()->state == threadSleeping)
|
||||||
|
halt();
|
||||||
|
|
||||||
|
stderrTypeWriteAppendCommand();
|
||||||
|
threadSleep(stderrDriverStepSettleMs);
|
||||||
|
while (currentThread()->state == threadSleeping)
|
||||||
|
halt();
|
||||||
|
|
||||||
|
stderrTypeReadCommand();
|
||||||
|
threadSleep(stderrDriverStepSettleMs);
|
||||||
|
while (currentThread()->state == threadSleeping)
|
||||||
|
halt();
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
halt();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 10700ms gives hereStringPipelineDriverThread's own total budget
|
||||||
|
(9000+500=9500ms, above its own real hcat/hsink spawn/run/reap time) a
|
||||||
|
comfortable margin before this thread ever touches the same shared
|
||||||
|
keyboard buffer, the same "next demo's initial delay clears the previous
|
||||||
|
demo's total typing budget" convention every driver thread above already
|
||||||
|
established. Settle is 600ms (slightly more than pipelineDriverThread's
|
||||||
|
own 500ms for a 2-stage pipe) since this demo's pipe has one more real
|
||||||
|
process (pipesrc, pipecat, AND pipesink) to spawn, run, and reap before
|
||||||
|
the final needle can print. */
|
||||||
|
#define threeStagePipelineDriverInitialDelayMs 10700
|
||||||
|
#define threeStagePipelineDriverSettleMs 600
|
||||||
|
|
||||||
|
static void threeStagePipelineTypeCommand(void)
|
||||||
|
{
|
||||||
|
injectKeyPress(scancodeMakeP);
|
||||||
|
injectKeyPress(scancodeMakeI);
|
||||||
|
injectKeyPress(scancodeMakeP);
|
||||||
|
injectKeyPress(scancodeMakeE);
|
||||||
|
injectKeyPress(scancodeMakeS);
|
||||||
|
injectKeyPress(scancodeMakeR);
|
||||||
|
injectKeyPress(scancodeCPressMake);
|
||||||
|
injectKeyPress(scancodeMakeSpace);
|
||||||
|
injectShiftedKeyPress(scancodeMakeBackslash);
|
||||||
|
injectKeyPress(scancodeMakeSpace);
|
||||||
|
injectKeyPress(scancodeMakeP);
|
||||||
|
injectKeyPress(scancodeMakeI);
|
||||||
|
injectKeyPress(scancodeMakeP);
|
||||||
|
injectKeyPress(scancodeMakeE);
|
||||||
|
injectKeyPress(scancodeCPressMake);
|
||||||
|
injectKeyPress(scancodeMakeA);
|
||||||
|
injectKeyPress(scancodeMakeT);
|
||||||
|
injectKeyPress(scancodeMakeSpace);
|
||||||
|
injectShiftedKeyPress(scancodeMakeBackslash);
|
||||||
|
injectKeyPress(scancodeMakeSpace);
|
||||||
|
injectKeyPress(scancodeMakeP);
|
||||||
|
injectKeyPress(scancodeMakeI);
|
||||||
|
injectKeyPress(scancodeMakeP);
|
||||||
|
injectKeyPress(scancodeMakeE);
|
||||||
|
injectKeyPress(scancodeMakeS);
|
||||||
|
injectKeyPress(scancodeMakeI);
|
||||||
|
injectKeyPress(scancodeMakeN);
|
||||||
|
injectKeyPress(scancodeMakeK);
|
||||||
|
injectKeyPress(scancodeMakeEnter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The live ring-3 proof for shell.c's new REAL N-stage pipeline
|
||||||
|
* (runPipelineStages/jobctlWaitPipelineStages) going past two stages: types
|
||||||
|
* "pipesrc | pipecat | pipesink" at the real interactive shell through the
|
||||||
|
* same injected-keystroke mechanism every driver thread above already
|
||||||
|
* uses, well after hereStringPipelineDriverThread's own total budget has
|
||||||
|
* finished with the shell's shared line buffer.
|
||||||
|
*
|
||||||
|
* pipesrc.c and pipesink.c are reused completely unchanged from the
|
||||||
|
* two-stage pipeline demo (FALA 29) -- their own narration ("wrote
|
||||||
|
* payload", "blocking on read, waiting for pipesrc", "payload-ok") is still
|
||||||
|
* literally true here, just relayed through one more real process instead
|
||||||
|
* of being directly adjacent. The new thing this demo actually proves is
|
||||||
|
* user/pipecat.c in the middle: jobctlSpawnPiped bakes a real pipe into
|
||||||
|
* BOTH its fd 0 (from pipesrc's pipe) and its fd 1 (to pipesink's pipe)
|
||||||
|
* before it ever runs a single instruction -- the first process in this
|
||||||
|
* kernel with two DIFFERENT real inter-process pipes on its stdio at once
|
||||||
|
* (hcat.c's own simultaneous piped-stdin-and-stdout, FALA 34, had a
|
||||||
|
* shell-fed here-string on the stdin side, never a second real pipe). The
|
||||||
|
* actual pass/fail proof is still entirely pipesink.c's own doing (its
|
||||||
|
* "payload-ok" needle only prints on an exact byte-for-byte match of
|
||||||
|
* whatever pipesrc originally wrote) -- this thread's only job is to type
|
||||||
|
* the command and give all three spawned processes (none of which ever
|
||||||
|
* sleeps or waits on a real timer) a comfortable amount of real scheduled
|
||||||
|
* time to run to completion.
|
||||||
|
*/
|
||||||
|
static void threeStagePipelineDriverThread(void)
|
||||||
|
{
|
||||||
|
threadSleep(threeStagePipelineDriverInitialDelayMs);
|
||||||
|
while (currentThread()->state == threadSleeping)
|
||||||
|
halt();
|
||||||
|
|
||||||
|
kprintf("[kbd] typing shell command for the three-stage pipeline demo\n");
|
||||||
|
jobctlTypeFlushLine();
|
||||||
|
threeStagePipelineTypeCommand();
|
||||||
|
|
||||||
|
threadSleep(threeStagePipelineDriverSettleMs);
|
||||||
|
while (currentThread()->state == threadSleeping)
|
||||||
|
halt();
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
halt();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* '=' (sysGetEnv/sysSetEnv's own operator, shell.c's `export N=V`
|
||||||
|
builtin), 'y'/'Y', and 'v'/'V' are the only three make codes no earlier
|
||||||
|
driver thread above ever needed -- every other letter "export",
|
||||||
|
"GREETING", "envprint", and "env" use (e,x,p,o,r,t,g,i,n,f,s,b) was
|
||||||
|
already defined by an earlier block. Cross-checked against
|
||||||
|
keyboard.c's own scancodeLower/scancodeUpper tables the same way every
|
||||||
|
block above documents for its own new codes. */
|
||||||
|
#define scancodeMakeEquals 0x0D
|
||||||
|
#define scancodeMakeY 0x15
|
||||||
|
#define scancodeMakeV 0x2F
|
||||||
|
|
||||||
|
static void envTypeExportCommand(void)
|
||||||
|
{
|
||||||
|
injectKeyPress(scancodeMakeE);
|
||||||
|
injectKeyPress(scancodeMakeX);
|
||||||
|
injectKeyPress(scancodeMakeP);
|
||||||
|
injectKeyPress(scancodeMakeO);
|
||||||
|
injectKeyPress(scancodeMakeR);
|
||||||
|
injectKeyPress(scancodeMakeT);
|
||||||
|
injectKeyPress(scancodeMakeSpace);
|
||||||
|
injectShiftedKeyPress(scancodeMakeG);
|
||||||
|
injectShiftedKeyPress(scancodeMakeR);
|
||||||
|
injectShiftedKeyPress(scancodeMakeE);
|
||||||
|
injectShiftedKeyPress(scancodeMakeE);
|
||||||
|
injectShiftedKeyPress(scancodeMakeT);
|
||||||
|
injectShiftedKeyPress(scancodeMakeI);
|
||||||
|
injectShiftedKeyPress(scancodeMakeN);
|
||||||
|
injectShiftedKeyPress(scancodeMakeG);
|
||||||
|
injectKeyPress(scancodeMakeEquals);
|
||||||
|
injectKeyPress(scancodeMakeF);
|
||||||
|
injectKeyPress(scancodeMakeR);
|
||||||
|
injectKeyPress(scancodeMakeO);
|
||||||
|
injectKeyPress(scancodeMakeS);
|
||||||
|
injectKeyPress(scancodeMakeT);
|
||||||
|
injectKeyPress(scancodeMakeB);
|
||||||
|
injectKeyPress(scancodeMakeY);
|
||||||
|
injectKeyPress(scancodeMakeT);
|
||||||
|
injectKeyPress(scancodeMakeE);
|
||||||
|
injectKeyPress(scancodeMakeEnter);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void envTypeEnvprintCommand(void)
|
||||||
|
{
|
||||||
|
injectKeyPress(scancodeMakeE);
|
||||||
|
injectKeyPress(scancodeMakeN);
|
||||||
|
injectKeyPress(scancodeMakeV);
|
||||||
|
injectKeyPress(scancodeMakeP);
|
||||||
|
injectKeyPress(scancodeMakeR);
|
||||||
|
injectKeyPress(scancodeMakeI);
|
||||||
|
injectKeyPress(scancodeMakeN);
|
||||||
}
|
}
|
||||||
|
|
||||||
void kmain(uint32 magic, uint64 multibootInfo)
|
void kmain(uint32 magic, uint64 multibootInfo)
|
||||||
|
|||||||
Reference in new issue
Block a user