mirror of
https://github.com/ARMSX2/ARMSX3.git
synced 2026-08-24 16:58:52 -07:00
Upstream bc22df8ba skips waking waiters after a SUCCESSFUL conditional store
when the SPU sits at pc 0x11e4 with the SPURS control block reserved, unless
byte 0x73 of that block shows this thread going running->idle. It is a
throughput optimisation: SPURS kernels store to that block constantly and
waking every waiter each time is a thundering herd.
Both constants are assumptions about one specific SPURS kernel build. 0x11e4
is a guest code address and 0x73 an offset inside the guest's control block,
and SPURS ships in many versions across titles. On a kernel whose layout
differs, the running->idle test reads the wrong byte, answers no forever, and
the store succeeds while every waiter stays asleep -- reported by nothing.
Tales of Xillia (BLUS31006) hangs with all five graphics SPUs reserving that
block, each suppressing ~100,000 notifications, ~4.85M conditional stores at
a 16.5% failure rate. Its SPURS kernel then executes its own HALT at
pc=0x00f00: r16 & r17 = 0x40000000, two workload masks that must be disjoint
both claiming workload bit 30. The group never joins, no frame is ever
presented again, and every PPU thread parks.
Whether the missed wakeups cause that inconsistency or merely accompany it is
NOT established. What is established is that notifying is correct and
suppressing is the optimisation, so the optimisation goes. Expect a
throughput cost on SPURS-heavy titles; it is measurable and revertable.
The counter is kept, now recording how often the heuristic would have
suppressed, so that cost shows up in a log instead of being guessed at.