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>
5.5 KiB
5.5 KiB
Phase C+15-α Schema-Wiring Audit (2026-05-14)
Phase 1 — Wired/unwired matrix (pre-session)
| Kind | Canary emits? | Ours emits? | Status (pre) | Priority |
|---|---|---|---|---|
schema_version |
yes | yes | wired | — |
import.call |
yes | yes | wired | — |
kernel.call |
yes | yes | wired (+C+10) | — |
kernel.return |
yes | yes | wired | — |
handle.create |
declared | declared | stubbed | HIGH |
handle.destroy |
declared | declared | stubbed | HIGH |
thread.create |
declared | declared | stubbed | HIGH |
thread.exit |
declared | declared | stubbed | HIGH |
wait.begin |
declared | declared | stubbed | HIGH |
wait.end |
declared | declared | stubbed | HIGH |
thread.suspend |
declared | not in API | unwired | LOW |
thread.resume |
declared | not in API | unwired | LOW |
vfs.open |
declared | not in API | redundant? | MEDIUM |
vfs.read |
declared | not in API | high-vol | LOW |
vfs.close |
declared | not in API | redundant? | MEDIUM |
mem.write |
declared | not in API | opt-in | LOW |
Phase 2/3 — Kinds wired this session
Wired symmetrically in both engines (cvar-gated default-off):
handle.create— emitted fromKernelState::alloc_handle_for(ours) /ObjectTable::AddHandle(canary). 39+ call sites covered via centralized hook.handle.destroy— emitted fromnt_close+xam_task_close_handle(ours) /ObjectTable::RemoveHandle(canary).thread.create— emitted fromex_create_thread(ours) /ExCreateThreadinxboxkrnl_threading.cc(canary). After spawn succeeds.thread.exit— emitted fromex_terminate_thread(ours) /XThread::Exit(canary). Canary'sXThread::Exitcovers both explicitExTerminateThreadand implicit thread-entry returns.wait.begin— emitted fromnt_wait_for_single_object_ex+ke_wait_for_single_object(ours) /xeKeWaitForSingleObject+NtWaitForSingleObjectEx(canary).
Deferred (v1.2):
wait.end— design challenge: wait can park the guest thread, and the wake-status path differs between engines. Sync outcome status is already captured in the immediately-followingkernel.return. Async wake outcome surfaced in subsequent events.thread.suspend/thread.resume— low-frequency; defer until needed.vfs.*— redundant withkernel.callfor Nt*File. Skip per schema-v1 audit recommendation.mem.write— opt-in only (separate cvar); high-volume.
Code summary
Ours (~140 LOC)
crates/xenia-kernel/src/event_log.rs— registry + auto helpers (register_handle_semantic_id,lookup_handle_semantic_id,forget_handle_semantic_id,emit_handle_create_auto,emit_handle_destroy_auto). +85 LOC.crates/xenia-kernel/src/objects.rs—KernelObject::schema_object_type(). +14 LOC.crates/xenia-kernel/src/state.rs—alloc_handle_foremit hook. +24 LOC.crates/xenia-kernel/src/exports.rs—nt_closedestroy emit,ex_create_threadthread.create emit,ex_terminate_threadthread.exit emit,nt_wait_for_single_object_ex+ke_wait_for_single_objectwait.begin emits,decode_timeout_nshelper. +85 LOC.
crates/xenia-kernel/src/xam.rs—xam_task_close_handledestroy emit. +14 LOC.
Canary (~130 LOC)
src/xenia/kernel/event_log.h— registry API (RegisterHandleSemanticId,LookupHandleSemanticId,ForgetHandleSemanticId,EmitHandleCreateAuto,EmitHandleDestroyAuto). +20 LOC.src/xenia/kernel/event_log.cc— per-tid counter map (was per-host-threadthread_local; produced duplicatetid_event_idxfor tid=0 across host threads — a bug in the pre-session implementation),CurrentTidnon-asserting via newXThread::TryGetCurrentThread, registry helpers, auto-emit wrappers. +60 LOC net.src/xenia/kernel/xthread.h+xthread.cc—TryGetCurrentThreadaccessorXThread::Exitthread.exit emit. +12 LOC.
src/xenia/kernel/util/object_table.cc—AddHandle/RemoveHandlehooksSchemaObjectTypemapping. +35 LOC.
src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc—ExCreateThreadthread.create emit,xeKeWaitForSingleObject+NtWaitForSingleObjectExwait.begin emits. +30 LOC.
Diff tool
tools/diff-events/diff_events.py—SKIP_PAYLOAD_FIELDS_BY_KINDnow skipshandle_semantic_id(cross-enginecreating_tiddiffers, so SIDs are engine-local),parent_tid,handles_semantic_ids,woken_by_semantic_id. +6 LOC.
Bug found and fixed this session
Pre-session bug: canary's t_tid_event_idx was a host-thread-local global,
not a tid-keyed counter. When AddHandle runs from multiple host threads with
tid==0 (boot init + early XThread bootstrap before guest tid is assigned), each
host thread had its own counter starting at 0, producing duplicate
tid_event_idx values within the tid=0 stream. The diff tool rejected the
file with "events out of order at index 8". Fixed by replacing the thread_local
with a tid-keyed std::unordered_map + mutex (matches ours's design).