Files
xenia-rs/audit-runs/phase-c15a-schema-wiring/audit.md
MechaCat02 ef93a4fa14 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>
2026-06-05 07:19:08 +02:00

103 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 from `KernelState::alloc_handle_for` (ours) /
`ObjectTable::AddHandle` (canary). 39+ call sites covered via centralized hook.
- **`handle.destroy`** — emitted from `nt_close` + `xam_task_close_handle` (ours) /
`ObjectTable::RemoveHandle` (canary).
- **`thread.create`** — emitted from `ex_create_thread` (ours) / `ExCreateThread`
in `xboxkrnl_threading.cc` (canary). After spawn succeeds.
- **`thread.exit`** — emitted from `ex_terminate_thread` (ours) / `XThread::Exit`
(canary). Canary's `XThread::Exit` covers both explicit `ExTerminateThread`
and implicit thread-entry returns.
- **`wait.begin`** — emitted from `nt_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-following `kernel.return`. Async wake outcome
surfaced in subsequent events.
- **`thread.suspend` / `thread.resume`** — low-frequency; defer until needed.
- **`vfs.*`** — redundant with `kernel.call` for 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_for` emit hook. +24 LOC.
- `crates/xenia-kernel/src/exports.rs``nt_close` destroy emit,
`ex_create_thread` thread.create emit, `ex_terminate_thread` thread.exit emit,
`nt_wait_for_single_object_ex` + `ke_wait_for_single_object` wait.begin emits,
+ `decode_timeout_ns` helper. +85 LOC.
- `crates/xenia-kernel/src/xam.rs``xam_task_close_handle` destroy 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-thread
`thread_local`; produced duplicate `tid_event_idx` for tid=0 across host
threads — a bug in the pre-session implementation), `CurrentTid` non-asserting
via new `XThread::TryGetCurrentThread`, registry helpers, auto-emit wrappers.
+60 LOC net.
- `src/xenia/kernel/xthread.h` + `xthread.cc``TryGetCurrentThread` accessor
+ `XThread::Exit` thread.exit emit. +12 LOC.
- `src/xenia/kernel/util/object_table.cc``AddHandle`/`RemoveHandle` hooks
+ `SchemaObjectType` mapping. +35 LOC.
- `src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc``ExCreateThread`
thread.create emit, `xeKeWaitForSingleObject` + `NtWaitForSingleObjectEx`
wait.begin emits. +30 LOC.
### Diff tool
- `tools/diff-events/diff_events.py``SKIP_PAYLOAD_FIELDS_BY_KIND` now skips
`handle_semantic_id` (cross-engine `creating_tid` differs, 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).