BT410 5.3.77: the overrun drain loop is not the trigger either

serialnamedpipe's P_RX_BLOCKED path drains its whole backlog when the guest
hasn't read in time -- directserial's `while (doReceive());`.  That looked
like the trigger, since a named pipe's backlog is unbounded where a real
port's is capped by the line rate.  Bounded it to one byte (real UART overrun
semantics) and re-ran the conf that had faulted 3/3: FAULT 283s, FAULT 226s,
FAULT 204s.  Killed.

The measurement that explains why it was never plausible: overruns during a
run are 1-3 per report period, because vRIO sends about a byte every 1-3ms --
the backlog is shallow and the loop had nothing to teleport.  The 494/499
counts all land after the game exits.  I read the code and inferred a burst
without measuring the queue depth it operates on.

Default restored to drain-all: it is the validated directserial behaviour the
RIO's rxpollus/rxburst tuning was calibrated against, and changing it on a
dead hypothesis would risk real-cockpit timing for nothing.
VPX_RX_OVERRUN_ONE=1 opts into the bounded form.

The roadmap now carries a fault ledger of every dead hypothesis so none get
re-run.  What survives: a deterministic DPMI-host path walking a
{next,handler} chain into a node whose pointer is an unhooked IVT value,
entered under RIO interrupt load.  Naming the owning routine needs a trace of
entries to host 0x66CF, clean vs faulting -- a DPMI32VM reversing
sub-project, now decoupled from the reconstruction (vRIO down = 100%
reliable, logged conf = ~70%).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-29 19:33:05 -05:00
co-authored by Claude Fable 5
parent d378148c14
commit e69d761fb8
10 changed files with 1981 additions and 689 deletions
@@ -1742,3 +1742,49 @@ The cage machinery in COCKPIT-CAGE-NOTES.md (punch-texel cutouts, glance-hide,
twist conjugation) now has its subject: this canopy is the a11/MAX_COP shell
those notes were written about, and it arrives through the authentic path
rather than the bridge's own fixture detection.
--------------------------------------------------------------------------------
ANOTHER HYPOTHESIS DOWN: THE OVERRUN DRAIN LOOP IS NOT THE TRIGGER
--------------------------------------------------------------------------------
serialnamedpipe's P_RX_BLOCKED path drains its whole backlog when the guest
has not read in time -- `while (doReceive());`, copied from directserial.
That looked like the trigger: a named pipe's backlog is unbounded where a
real port's is capped by the line rate, so the loop could teleport a burst
into the UART in zero guest-time. Bounded it to one byte (real UART overrun
semantics) and re-ran the conf that had faulted 3/3.
pod_render_quiet, bounded drain: FAULT 283s, FAULT 226s, FAULT 204s
3/3 again. Killed. And the measurement that explains WHY it was never
plausible: overruns DURING a run are 1-3 per report period, because vRIO
sends about one byte every 1-3ms -- the backlog is shallow and the loop
never had anything to teleport. (The 494/499 counts in the logs all land
AFTER the game exits.) I read the code and inferred a burst without first
measuring the queue depth the code operates on.
The drain-all DEFAULT IS RESTORED -- it is the validated directserial
behaviour the RIO's rxpollus/rxburst tuning was calibrated against, and
changing it on a dead hypothesis would risk real-cockpit timing for nothing.
VPX_RX_OVERRUN_ONE=1 opts into the bounded form if a later experiment wants
it.
FAULT LEDGER (what is dead, so nobody re-runs these):
* the skeleton walk (predates it; env-gated A/B)
* ESP drift / stack size (probe: drift=0; PE geometry equal)
* priority-0 starvation / deadlock ([queues] + nextReady)
* EulerAngles::operator= (probe never fired; address is host)
* the VPX ack heuristic (reproduces after the fix)
* our debug logging (removing it makes it WORSE)
* the RIO test-mode handshake (quiet run's init passed, faulted)
* the overrun drain loop (this entry)
* Torso attribute truncation -- NOT dead: real, and took the
rate from 100%% to ~25-40%%
WHAT SURVIVES: a deterministic DPMI-host code path (identical registers every
catch) that walks a {next,handler} chain and meets a node whose pointer is an
unhooked IVT value; entered under RIO interrupt load; probability modulated by
anything that shifts guest timing. The only remaining route in is naming the
routine that owns that chain, which needs a trace of entries to host 0x66CF
with the head node -- clean run vs faulting run. That is a DPMI32VM reversing
sub-project, and it is now decoupled from the reconstruction: with vRIO down
the pod is 100%% reliable, and with the logged conf it is ~70%%.