diff --git a/crates/xenia-app/src/main.rs b/crates/xenia-app/src/main.rs index 1b14bbc..004dad6 100644 --- a/crates/xenia-app/src/main.rs +++ b/crates/xenia-app/src/main.rs @@ -2016,6 +2016,24 @@ fn coord_idle_advance( shutdown: &Option>, stats: &ExecStats, ) -> RoundCtl { + // Path β (iterate-2.BE follow-up): when the scheduler has no Ready + // threads, `coord_pre_round`'s instruction-count vsync ticker stops + // advancing (instruction_count is frozen). That starves the + // host-driven graphics ISR dispatcher: queue stays empty, no + // deliveries occur, and the very stall we're trying to break out of + // gets worse. Tick vsync from wallclock here unconditionally — it's + // a host-clock read, independent of instruction count, and the + // dispatcher in the outer loop will drain whatever we queue on the + // next pass. Mirrors the `--parallel` ticker choice in + // `coord_pre_round` (`tick_vsync_wallclock` branch). + if kernel.interrupts.tick_vsync_wallclock() { + use std::sync::atomic::Ordering; + let mmio = kernel.gpu.mmio(); + let prev = mmio.d1mode_vblank_vline_status.load(Ordering::Relaxed); + mmio.d1mode_vblank_vline_status + .store(prev | 0x1, Ordering::Relaxed); + } + let next_timer = kernel.earliest_timer_deadline(); let next_wait = kernel.scheduler.earliest_wait_deadline(); let target = match (next_timer, next_wait) {