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:
106
audit-runs/phase-c7-keSetEvent/fix-c7-only.diff
Normal file
106
audit-runs/phase-c7-keSetEvent/fix-c7-only.diff
Normal file
@@ -0,0 +1,106 @@
|
||||
# Phase C+7-only diff (synthesized from working tree minus cumulative C+5/C+6/C+6½/XAM changes)
|
||||
#
|
||||
# Full uncommitted diff is in `fix.diff` (1431 lines, includes all
|
||||
# pre-existing Phase C work since HEAD).
|
||||
#
|
||||
# This file isolates the ~30 LOC body changes + ~160 LOC test additions
|
||||
# that constitute Phase C+7.
|
||||
|
||||
--- a/crates/xenia-kernel/src/exports.rs (C+6½ baseline)
|
||||
+++ b/crates/xenia-kernel/src/exports.rs (C+7)
|
||||
|
||||
# Body 1: ke_set_event — match canary's constant-1 return (xevent.cc:60-64)
|
||||
|
||||
-fn ke_set_event(ctx: &mut PpcContext, mem: &GuestMemory, state: &mut KernelState) {
|
||||
- let h = ctx.gpr[3] as u32;
|
||||
- ensure_dispatcher_object(state, mem, h);
|
||||
- let previous = match state.objects.get_mut(&h) {
|
||||
- Some(KernelObject::Event { signaled, .. }) => {
|
||||
- let prev = *signaled;
|
||||
- *signaled = true;
|
||||
- prev as u32
|
||||
- }
|
||||
- _ => 0,
|
||||
- };
|
||||
- state.audit_signal(h, ctx.lr as u32, "KeSetEvent", previous as u64);
|
||||
- wake_eligible_waiters(state, h);
|
||||
- ctx.gpr[3] = previous as u64;
|
||||
-}
|
||||
+fn ke_set_event(ctx: &mut PpcContext, mem: &GuestMemory, state: &mut KernelState) {
|
||||
+ let h = ctx.gpr[3] as u32;
|
||||
+ ensure_dispatcher_object(state, mem, h);
|
||||
+ // Canary parity (xevent.cc:60-64): `XEvent::Set` returns constant `1`
|
||||
+ // on success, NOT the prior signaled state as the NT contract claims.
|
||||
+ // We compute `previous` for internal bookkeeping (audit_signal,
|
||||
+ // wake_eligible_waiters honor the prior-state read), but report
|
||||
+ // `1` for success / `0` for "no dispatcher found" to match the
|
||||
+ // canary Phase A oracle. See Phase C+7 investigation.md.
|
||||
+ let (previous, found) = match state.objects.get_mut(&h) {
|
||||
+ Some(KernelObject::Event { signaled, .. }) => {
|
||||
+ let prev = *signaled;
|
||||
+ *signaled = true;
|
||||
+ (prev as u32, true)
|
||||
+ }
|
||||
+ _ => (0u32, false),
|
||||
+ };
|
||||
+ state.audit_signal(h, ctx.lr as u32, "KeSetEvent", previous as u64);
|
||||
+ wake_eligible_waiters(state, h);
|
||||
+ ctx.gpr[3] = if found { 1 } else { 0 };
|
||||
+}
|
||||
|
||||
# Body 2: nt_set_event — out-pointer writes constant 1 not prior state
|
||||
# (xboxkrnl_threading.cc:610-628 + xevent.cc:60-64 chain)
|
||||
|
||||
-fn nt_set_event(ctx: &mut PpcContext, mem: &GuestMemory, state: &mut KernelState) {
|
||||
- let handle = ctx.gpr[3] as u32;
|
||||
- let prev_ptr = ctx.gpr[4] as u32;
|
||||
- let previous = match state.objects.get_mut(&handle) {
|
||||
- Some(KernelObject::Event { signaled, .. }) => {
|
||||
- let prev = *signaled;
|
||||
- *signaled = true;
|
||||
- prev as u32
|
||||
- }
|
||||
- _ => 0,
|
||||
- };
|
||||
- state.audit_signal(handle, ctx.lr as u32, "NtSetEvent", previous as u64);
|
||||
- wake_eligible_waiters(state, handle);
|
||||
- if prev_ptr != 0 {
|
||||
- mem.write_u32(prev_ptr, previous);
|
||||
- }
|
||||
- ctx.gpr[3] = STATUS_SUCCESS;
|
||||
-}
|
||||
+fn nt_set_event(ctx: &mut PpcContext, mem: &GuestMemory, state: &mut KernelState) {
|
||||
+ let handle = ctx.gpr[3] as u32;
|
||||
+ let prev_ptr = ctx.gpr[4] as u32;
|
||||
+ // Canary parity (xboxkrnl_threading.cc:610-628): the optional out-pointer
|
||||
+ // is filled with `was_signalled` = `ev->Set()` = constant 1 (see
|
||||
+ // xevent.cc:60-64), NOT the prior signaled state. r3 carries
|
||||
+ // STATUS_SUCCESS. We retain `previous` for internal audit/wake plumbing.
|
||||
+ let (previous, found) = match state.objects.get_mut(&handle) {
|
||||
+ Some(KernelObject::Event { signaled, .. }) => {
|
||||
+ let prev = *signaled;
|
||||
+ *signaled = true;
|
||||
+ (prev as u32, true)
|
||||
+ }
|
||||
+ _ => (0u32, false),
|
||||
+ };
|
||||
+ state.audit_signal(handle, ctx.lr as u32, "NtSetEvent", previous as u64);
|
||||
+ wake_eligible_waiters(state, handle);
|
||||
+ if prev_ptr != 0 && found {
|
||||
+ mem.write_u32(prev_ptr, 1);
|
||||
+ }
|
||||
+ ctx.gpr[3] = STATUS_SUCCESS;
|
||||
+}
|
||||
|
||||
# Test additions (in tests module): 6 new unit tests; see file lines 7179-7340
|
||||
# - ke_set_event_returns_constant_one_on_unsignaled_auto_reset
|
||||
# - ke_set_event_returns_constant_one_on_already_signaled_manual_reset
|
||||
# - nt_set_event_null_prev_ptr_returns_status_success_no_write
|
||||
# - nt_set_event_valid_prev_ptr_writes_constant_one_and_returns_success
|
||||
# - nt_set_event_on_signaled_event_writes_one
|
||||
# - ke_set_event_post_fix_still_wakes_waiter
|
||||
|
||||
# LOC summary (Phase C+7 only, additive on C+6½ baseline):
|
||||
# body changes: ~14 net added lines across 2 functions
|
||||
# test additions: ~160 lines (6 tests)
|
||||
# total: ~174 LOC, 1 file
|
||||
Reference in New Issue
Block a user