Files
xenia-rs/docs/functions/sub_8245EC10.md
MechaCat02 ad45873a1b ITERATE-2.V: scheduler priority aging closes 18-day AUDIT-049 wedge
Priority aging in xenia-cpu/scheduler.rs:pick_runnable
(effective_priority = base + age_bonus(now_round - last_run_round),
capped at +31, AGING_ROUNDS_PER_BONUS=1). Strict-priority was parking
priority=0 threads behind CPU-bound priority=15 audio mixer
(sub_824D1328 guest spinwait at PC=0x824d1404 on CPU5). Aging
eventually picks the starved thread, breaking the producer-consumer
cycle that caused 5-tid wedge at PC=0x824ac578 since AUDIT-049 (10 May).

Cascade observed: tid=13 clean exit; events 121K -> 13M (107x); last
host_ns 767ms -> 51,011ms (66x); 8 new threads spawn; VdSwap 1 -> 2.

Complete two-day iterate sequence (2026-05-27 -> 2026-05-28):
- 2.F: VdSwap drain timeout 900ms -> 1ms (xenia-gpu/handle.rs); 876x
       perf win on VdSwap kernel callback
- 2.H: vA0000000 physical heap bucket added (state.rs, exports.rs);
       ctx_ptrs now in 0xA0000000-0xBFFFFFFF range matching canary
- 2.L: Phase-A diff harness categorized [return_value mismatch],
       [status mismatch], [args_resolved.path mismatch] tags
       (tools/diff-events/diff_events.py); closes reading-error #41
       (silent test-harness state leak invalidating trace diffs)
- 2.M: always-on exit-thread-state.json sibling to Phase-A JSONL
       (event_log.rs + xenia-app/main.rs); closes reading-error #42
       (Phase-A blind to blocked-forever waits)
- 2.Q: signal.match kernel instrumentation in NtSetEvent /
       NtReleaseSemaphore / KeSetEvent / KeReleaseSemaphore
       (exports.rs); emits target_handle + waiter_count + waiter_tids
- 2.T: wake.requested kernel instrumentation in wake_eligible_waiters
       (exports.rs); emits target_tid + transition + new_state
- 2.V: scheduler priority aging (xenia-cpu/scheduler.rs) [keystone]

Plus accumulated WIP from earlier May (contention_manifest,
phase_b_snapshot, xam/xaudio enhancements, analysis db, xex loader,
xenia-app main loop, etc.). Audit-runs/ artifacts remain untracked
per project convention.

Tests: 300 xenia-cpu / 227 xenia-kernel / 5 xenia-app / 19 xenia-path
/ 30+ smaller suites -- all PASS, 0 regressions. Determinism preserved
(2x cold runs bit-identical at 13,003,881 events post-2.V).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 07:27:26 +02:00

56 lines
3.4 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.
---
address: 0x8245EC10
classification: dispatch_table_method
confidence: high
last_audit: 060
aliases:
- "canary γ-wedge signaler B"
- "dispatch_table 0x820B5830 slot 1"
---
# sub_8245EC10 — dispatch_table slot 1 method, canary γ-wedge signaler B
## Synopsis
Method living at slot 1 of `dispatch_table @ 0x820B5830`. The dispatch table is installed at struct offset 0 (vptr) by [sub_8245FEB8](sub_8245FEB8.md). In canary, this method is one of two NtSetEvent caller-LRs that signal the AUDIT-059 file-IO completion wedge dup handle (LR `0x8245ED80` post-`bl 0x824AA2F0`). In ours it fires 2× total but not on the wedge handle.
## Evidence
- Located at slot 1 of dispatch table `0x820B5830`. Slot 0 is `sub_8245F1D0`.
- The dispatch table is referenced from:
- `sub_8245F1D0+0x1C` (self-recursive)
- `sub_8245FEB8+0x100` (= `0x8245FFC0`, the `stw r11, 0(r31)` vtable install)
- AUDIT-060 Probe O ours: fires **2× in ours** (`--ctor-probe`); both fires come from `sub_8245FEB8` callers (transitively, via the installed dispatch-table dispatch).
- AUDIT-059 Probe C canary: at LR `0x8245ED80` (`= sub_8245EC10+0x170` or similar internal PC after `bl 0x824AA2F0`), this fn is one of two distinct canary NtSetEvent caller-fns that signal the wedge dup handle (per cross-run `r31` invariant; the other is [sub_82458B90](sub_82458B90.md)).
- Both canary signalers wrap `bl 0x824AA2F0` (NtSetEvent wrapper). Each fires once per file-IO completion in canary.
## Activation
Indirect dispatch. Reachable only via `bctrl` against an object whose vptr was set to `dispatch_table @ 0x820B5830`. The install happens via [sub_8245FEB8](sub_8245FEB8.md). No direct `bl` callers — and that is correct for a `dispatch_table_method`.
## Static graph
- Static callers (direct `bl`): **0** (correct — indirect dispatch only).
- Callees: includes `bl 0x824AA2F0` (NtSetEvent wrapper) at internal PC near `+0x170` (canary LR `0x8245ED80`).
## Audit log
- **AUDIT-060 (2026-05-12)** — fires 2× in ours; not dead. AUDIT-059's "dead via 0 static callers" framing was too narrow — dispatch_table reachability needs runtime-installed-vptr awareness, not just static `bl` xref BFS. [confirmed alive]
- **AUDIT-059 (2026-05-11)** — identified as canary NtSetEvent signaler B for the file-IO completion wedge dup handle. Cross-run `(tid, r31)` invariant matched. [confirmed for canary signaler role]
- **AUDIT-059 (2026-05-11)** — claimed dead in ours due to 0 static callers + dispatch-table installer ([sub_8245FEB8](sub_8245FEB8.md)) ALSO claimed dead. [STATUS: falsified by AUDIT-060]
## Open questions
- What handle does `sub_8245EC10` signal in ours? (Two fires — capture r3 at each fire to identify the target handles.)
- Why doesn't it signal the wedge handle in ours? Either (a) it's running on the wrong object (different installed instance), or (b) the work item it's processing has a different completion-event field.
- Cross-engine method match: is canary fire #1 and ours fire #1 the same logical event? Compare object base (would need new instrumentation).
## Cross-references
- Installed at: `dispatch_table @ 0x820B5830` slot 1.
- Vptr installer: [sub_8245FEB8](sub_8245FEB8.md).
- Sibling method (slot 0): `sub_8245F1D0` (not yet dossierd).
- Sibling canary signaler: [sub_82458B90](sub_82458B90.md).
- Audits: 059, 060.
- Artifacts: `audit-runs/audit-059-gamma-wedge/canary-setwrapper.log`, `audit-runs/audit-060-fnptr-array-bootstrap/`.