Initial commit
Signed-off-by: Robert Allan James <robert.allan.james@gmail.com>
This commit is contained in:
+51
-3
@@ -141,6 +141,16 @@ static int g_idle_pump_active; /* zero-initialized (BSS) */
|
||||
|
||||
static void sk_repl_idle(VM *active_vm)
|
||||
{
|
||||
/* Close any dangling output line before this bottom half emits its own
|
||||
* chatter (xhci attach/detach progress, block-subsystem notices). If we
|
||||
* are mid-prompt-line -- the REPL started the attach while sitting at
|
||||
* "ok> " -- a bare console_println() would otherwise glue its text onto
|
||||
* the prompt and inherit no {VMName} prefix (g_line_start is 0). A
|
||||
* fresh line first keeps every idle line prefix-tagged and readable,
|
||||
* matching what an interactive typing session expects. No-op when the
|
||||
* console is already at a line boundary. */
|
||||
console_ensure_line_start();
|
||||
|
||||
/* Artemis Milestone 2d: xHCI Event Ring servicing. This is exactly the
|
||||
* "interrupt-driven, coarse cadence, cheap early-exit" trigger Section
|
||||
* U item 6 asked for -- xhci_poll_events() is a no-op read (loop
|
||||
@@ -498,11 +508,22 @@ int sk_console_key_available(void)
|
||||
* for the REPL's own top-level prompt, since it's the same underlying
|
||||
* console. Any g_console_pending_key left over from a ?TERMINAL peek is
|
||||
* consumed first so a line read never drops a byte ?TERMINAL already saw.
|
||||
* @param reanchor_prompt nonzero from the REPL's own prompt sites (which
|
||||
* print SK_PROMPT_TEXT immediately before): re-print the prompt whenever an
|
||||
* idle bottom half wrote to the console while this call blocked at the bare
|
||||
* prompt (see the re-anchor block in the idle branch). shim.c's fgets()
|
||||
* passes 0 -- its prompt context is caller-owned.
|
||||
*===========================================================================*/
|
||||
|
||||
int sk_console_readline(char *buf, int size, VM *active_vm)
|
||||
int sk_console_readline(char* buf, int size, VM* active_vm, int reanchor_prompt)
|
||||
{
|
||||
int n = 0;
|
||||
/* TX counter value right after the caller printed its prompt. Any
|
||||
* console output that lands while this readline blocks (heartbeat
|
||||
* status, sk_repl_idle()'s USB attach/detach chatter) pushes the
|
||||
* counter past this mark and away from a bare prompt; when that
|
||||
* happens, re-anchor the prompt (below). */
|
||||
uint64_t prompt_tx_mark = console_tx_count();
|
||||
|
||||
buf[0] = '\0';
|
||||
console_fb_draw_cursor(); /* show the cursor at the bare prompt, before any input */
|
||||
@@ -531,6 +552,33 @@ int sk_console_readline(char *buf, int size, VM *active_vm)
|
||||
g_last_beat_tick = now;
|
||||
sk_repl_idle(active_vm);
|
||||
}
|
||||
|
||||
/*
|
||||
* Re-anchor the prompt (FABRIC.md 4.4a unified prompt: print
|
||||
* only "ok> " here -- console_putc() auto-prefixes the current
|
||||
* [VMName] on a fresh line). When an idle bottom half above
|
||||
* pushed output past prompt_tx_mark, the console cursor is now
|
||||
* below/after new lines and the "ok> " the caller printed has
|
||||
* been scrolled or buried -- once the flood passes, the screen
|
||||
* and serial log would end on a stale line with no prompt
|
||||
* (FABRIC-3.md: the bare prompt must be the last thing shown
|
||||
* while the REPL sits idle). Reprinting it restores that
|
||||
* invariant. Skipped while a line is being edited (n > 0) so
|
||||
* partial echo stays attached to its own prompt; shim.c's
|
||||
* fgets() (QUERY/EXPECT/ACCEPT) calls in with reanchor_prompt
|
||||
* == 0 for the same reason -- its prompt line is caller-owned
|
||||
* text, not the REPL's. Each silent beat leaves the mark
|
||||
* unchanged, so the final state after the chatter dies down is
|
||||
* a fresh prompt on the last visible line, cursor on it.
|
||||
*/
|
||||
if (reanchor_prompt && n == 0 &&
|
||||
console_tx_count() != prompt_tx_mark)
|
||||
{
|
||||
console_puts(SK_PROMPT_TEXT);
|
||||
console_fb_draw_cursor();
|
||||
prompt_tx_mark = console_tx_count();
|
||||
}
|
||||
|
||||
/*
|
||||
* Do NOT use hlt here: QEMU single-threaded TCG can't process
|
||||
* its APIC timer callbacks while the guest CPU is halted (the
|
||||
@@ -720,7 +768,7 @@ int sk_repl_step(VM *vm)
|
||||
console_puts(SK_PROMPT_TEXT);
|
||||
}
|
||||
|
||||
sk_console_readline(input, sizeof(input), vm);
|
||||
sk_console_readline(input, sizeof(input), vm, 1);
|
||||
|
||||
if (input[0] == '\0') {
|
||||
console_puts(" ok\n");
|
||||
@@ -763,7 +811,7 @@ void sk_repl_run(VM *vm)
|
||||
* step()'s matching comment above. */
|
||||
console_puts(SK_PROMPT_TEXT);
|
||||
|
||||
sk_console_readline(input, sizeof(input), active);
|
||||
sk_console_readline(input, sizeof(input), active, 1);
|
||||
|
||||
if (input[0] == '\0') {
|
||||
console_puts(" ok\n");
|
||||
|
||||
Reference in New Issue
Block a user