handoff: VSync/event-wedge fixes + iterate 2.A–2.BC research notes

Source changes (dormant parity infra, retained from iterate 2.AI/2.AO):
- xenia-kernel/exports.rs: nt_create_event manual_reset polarity +
  related event wiring
- xenia-gpu/mmio_region.rs: D1MODE_VBLANK_VLINE_STATUS hardcode parity

Also lands the audit-runs/ analysis notes (.md/.txt/.json digests) for the
iterate 2.x VSync/0x10e8/0x1004 wedge investigation. Raw trace dumps
(.jsonl/.gz/.csv/.stdout) and agent worktrees (.claude/) are gitignored as
regenerable local artifacts — see memory + HANDOFF for the running findings.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-06-05 07:19:08 +02:00
parent acd1656753
commit ef93a4fa14
620 changed files with 108303 additions and 1 deletions

View File

@@ -0,0 +1,97 @@
#!/usr/bin/env python3
"""Phase C+23 jitter profile probe.
Reads canary jsonls (jitter-1/2/3 + cold-c21 + any fresh runs) and extracts:
- total tid=6 events seen within the first ~120k indices
- the exact event sequence on tid=6 around idx [104,595..104,620]
- count of wait.begin events on tid=6 by SID
- count of contention-prone events (wait.begin, kernel.call RtlEnter / RtlLeave)
Designed to stream line-by-line and not load multi-GB jsonls into RAM.
"""
import json
import os
import sys
from collections import Counter, defaultdict
WINDOW_LO = 104_595
WINDOW_HI = 104_620
TID = 6
TID_EVENT_LIMIT = 120_000
def profile(path: str):
if not os.path.exists(path):
return None
tid6_events = 0
waitbegins = Counter()
importcalls = Counter()
kernelcalls = Counter()
window_events = []
tid_idx = -1
with open(path, "rb") as fh:
for raw in fh:
# Cheap reject before json parse: must contain `"tid":6,`
if b'"tid":6,' not in raw and b'"tid": 6,' not in raw:
continue
try:
ev = json.loads(raw)
except Exception:
continue
if ev.get("tid") != TID:
continue
tid_idx = ev.get("tid_event_idx", tid_idx + 1)
tid6_events += 1
kind = ev.get("kind", "")
if kind == "wait.begin":
sids = ev.get("payload", {}).get("handles_semantic_ids") or []
for s in sids:
waitbegins[s] += 1
elif kind == "import.call":
name = ev.get("payload", {}).get("name", "")
importcalls[name] += 1
elif kind == "kernel.call":
name = ev.get("payload", {}).get("name", "")
kernelcalls[name] += 1
if WINDOW_LO <= tid_idx <= WINDOW_HI:
summary = {
"idx": tid_idx,
"kind": kind,
"name": ev.get("payload", {}).get("name", ""),
}
if kind == "wait.begin":
summary["sid"] = (ev.get("payload", {}).get("handles_semantic_ids") or [None])[0]
summary["timeout_ns"] = ev.get("payload", {}).get("timeout_ns")
window_events.append(summary)
if tid_idx > TID_EVENT_LIMIT:
break
return {
"path": path,
"tid6_total_seen": tid6_events,
"waitbegins_by_sid": dict(waitbegins.most_common(10)),
"rtlenter_calls": importcalls.get("RtlEnterCriticalSection", 0),
"rtlleave_calls": importcalls.get("RtlLeaveCriticalSection", 0),
"window_events": window_events,
}
def main(paths):
out = {}
for p in paths:
print(f"profiling {p}...", file=sys.stderr)
r = profile(p)
if r is None:
print(f" (missing)", file=sys.stderr)
continue
out[os.path.basename(p)] = r
json.dump(out, sys.stdout, indent=2)
print()
if __name__ == "__main__":
main(sys.argv[1:])