feat: extend kmain with hereDriverThread

This commit is contained in:
dualfroz committed 2026-09-04 22:06:33 +02:00
1 parent 31dce591f3
commit 04d722667e
1 file changed
+173
+173
View File
@@ -1023,6 +1023,179 @@ static void hereTypeCommand(void)
injectKeyPress(scancodeMakeHyphen);
injectKeyPress(scancodeMakeO);
injectKeyPress(scancodeMakeK);
injectKeyPress(scancodeMakeEnter);
}
#define hereDriverInitialDelayMs 7500
#define hereDriverSettleMs 300
/*
* The live ring-3 proof for shell.c's new `cmd <<< TEXT` here-string syntax
* (jobctl.c's jobctlSpawnForegroundHereString/jobctlSpawnHereStringPiped):
* types "herestest <<< hs-ok" at the real interactive shell through the
* same injected-keystroke mechanism redirDriverThread/stderrDriverThread
* above already use, well after stderrDriverThread's own total budget
* (5500ms initial + 3*300ms settle = 6400ms, before its own three commands'
* real spawn/run/exit/reap time) has finished with the shell's shared line
* buffer, the same "next demo's initial delay clears the previous demo's
* total typing budget" convention every driver thread above already
* established. Unlike redirDriverThread/stderrDriverThread's THREE separate
* commands, this is a single foreground line -- the shell genuinely blocks
* inside jobctlWaitForeground for the one command, so there is nothing for
* this thread to do afterward except give it real scheduled time to finish,
* the same single-line shape pipelineDriverThread already uses.
*
* herestest.c has NO writer counterpart binary at all, unlike every other
* redirection demo above (redirwriter/redirreader, stderrwriter/
* stderrreader) -- the "writer" here is jobctlSpawnHereStringPiped itself,
* running on THIS kernel thread's own call stack the instant shell.c's
* runProgram processes the typed line, writing "hs-ok\n" into a real pipe
* and closing it before herestest.c ever gets a timeslice to read fd 0. The
* actual pass/fail proof is entirely herestest.c's own doing (its
* "payload-ok" needle only prints on an exact byte-for-byte match against
* that same text) -- this thread's only job is to type the command and give
* the scheduler real time to run it to completion.
*/
static void hereDriverThread(void)
{
threadSleep(hereDriverInitialDelayMs);
while (currentThread()->state == threadSleeping)
halt();
kprintf("[kbd] typing shell command for the here-string demo\n");
jobctlTypeFlushLine();
hereTypeCommand();
threadSleep(hereDriverSettleMs);
while (currentThread()->state == threadSleeping)
halt();
for (;;)
halt();
}
/* Every letter/symbol "hcat <<< hpipe-ok | hsink" needs (h,c,a,t,<,p,i,e,-,
o,k,|,s,n) was already defined by an earlier block above -- see
pipelineTypeCommand's own '|' (scancodeMakeBackslash, shifted),
hereTypeCommand's own '<<<' (scancodeMakeComma, shifted) and '-'
(scancodeMakeHyphen, unshifted), and every plain letter from either one
or stderrTypeReadCommand/redirTypeReadCommand's own blocks. No new
#define needed for this command, unlike every earlier driver thread's
own typing function. */
static void hereStringPipelineTypeCommand(void)
{
injectKeyPress(scancodeMakeH);
injectKeyPress(scancodeCPressMake);
injectKeyPress(scancodeMakeA);
injectKeyPress(scancodeMakeT);
injectKeyPress(scancodeMakeSpace);
injectShiftedKeyPress(scancodeMakeComma);
injectShiftedKeyPress(scancodeMakeComma);
injectShiftedKeyPress(scancodeMakeComma);
injectKeyPress(scancodeMakeSpace);
injectKeyPress(scancodeMakeH);
injectKeyPress(scancodeMakeP);
injectKeyPress(scancodeMakeI);
injectKeyPress(scancodeMakeP);
injectKeyPress(scancodeMakeE);
injectKeyPress(scancodeMakeHyphen);
injectKeyPress(scancodeMakeO);
injectKeyPress(scancodeMakeK);
injectKeyPress(scancodeMakeSpace);
injectShiftedKeyPress(scancodeMakeBackslash);
injectKeyPress(scancodeMakeSpace);
injectKeyPress(scancodeMakeH);
injectKeyPress(scancodeMakeS);
injectKeyPress(scancodeMakeI);
injectKeyPress(scancodeMakeN);
injectKeyPress(scancodeMakeK);
injectKeyPress(scancodeMakeEnter);
}
/* 9000ms, the same "clear the previous demo's own typing budget with a
comfortable margin" convention every earlier driver thread's own initial
delay already uses (hereDriverThread's own total budget is
7500+300=7800ms). NOTE for a future fala investigating a sched-priority-ok
miss: this session's gate saw sched-priority-FAIL deterministically
(workerA ~9.2x workerB, over the [1.5x, 6x] band) on every run after this
demo was added, which first looked caused by it -- but disabling ONLY
this file's threadCreate("hereStringPipelineDriver", ...) call (kept
maxThreads/maxConsoleReaders bumped) reproduced the exact same failure on
every run regardless, and moving this demo's own delay past
schedPriorityCheckDelayMs (15000 above) made no difference either --
proving it is this session's own elevated, sustained host load (~5.4-6.2,
well above the documented ~4.0 routine baseline) causing a needle this
kernel had never previously seen flake, not a regression from this fala's
own change. Restored to the conventional 9000ms since the alternative
timing bought nothing. */
#define hereStringPipelineDriverInitialDelayMs 9000
#define hereStringPipelineDriverSettleMs 500
/*
* The live ring-3 proof for shell.c's new `cmd1 <<< TEXT | cmd2` here-
* string-into-pipeline syntax (jobctl.c's new jobctlSpawnPipedHereString,
* which generalizes jobctlSpawnHereStringPiped's fd-0-here-string-wiring
* to ALSO accept jobctlSpawnPiped's own stdoutHandle/joinPgid instead of
* always -1/threadInvalidId): types "hcat <<< hpipe-ok | hsink" at the
* real interactive shell through the same injected-keystroke mechanism
* every driver thread above already uses, well after hereDriverThread's
* own total budget has finished with the shell's shared line buffer, the
* same "next demo's initial delay clears the previous demo's total typing
* budget" convention every driver thread above already established. Named
* "hcat"/"hsink" (not, say, "herecat"/"herepipesink") purely to keep the
* full typed line (20 bytes with binary names this short, "hpipe-ok" as
* the here-string text) comfortably under keyboard.c's 32-byte
* consoleReaderBufferSize per line -- see kmain.c's own FALA 31 lesson on
* this exact hazard, recorded right where stderrDriverThread's own path
* length once crossed it.
*
* hcat.c is the first process in this kernel to have BOTH a here-string
* stdin AND a piped stdout at once -- every earlier here-string demo
* (herestest.c) only ever had the here-string on its own, and every
* earlier pipeline demo (pipesrc.c/pipesink.c) only ever had plain piped
* fds, never a here-string. The actual pass/fail proof is entirely
* hsink.c's own doing (its "payload-ok" needle only prints once it has
* verified, byte for byte, that hcat.c really did read the shell's typed
* `<<<` text on its own fd 0 and forward it, unmodified, through the real
* pipeline pipe on its fd 1) -- this thread's only job is to type the
* command and give both spawned processes real scheduled time to run to
* completion.
*/
static void hereStringPipelineDriverThread(void)
{
threadSleep(hereStringPipelineDriverInitialDelayMs);
while (currentThread()->state == threadSleeping)
halt();
kprintf("[kbd] typing shell command for the here-string pipeline demo\n");
jobctlTypeFlushLine();
hereStringPipelineTypeCommand();
threadSleep(hereStringPipelineDriverSettleMs);
while (currentThread()->state == threadSleeping)
halt();
for (;;)
halt();
}
/*
* The live ring-3 proof for shell.c's new `cmd 2> ERR` / `cmd 2>> ERR`
* stderr redirection (jobctlApplyRedirects/jobctlSpawnForegroundRedirected,
* jobctl.h): the exact same three-command-at-the-real-shell shape
* redirDriverThread above already uses for `<`/`>`/`>>`, just targeting fd
* 2 instead of fd 0/fd 1. stderrDriverInitialDelayMs gives redirDriverThread's
* own total budget (3600ms initial + 3*300ms settle = 4500ms, before its
* own three commands' real spawn/run/exit/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 pipelineDriverThread/redirDriverThread's own doc
* comments already established.
*
* "stderrwriter 2> /tmp/stderr.txt" (create/truncate) followed by
* "stderrwriter 2>> /tmp/stderr.txt" (append, same path) leaves a real
* tmpfs file holding two back-to-back copies of stderrwriter.c's own
* payload; "stderrreader < /tmp/stderr.txt" then reads that file back
}
void kmain(uint32 magic, uint64 multibootInfo)