mirror of
https://github.com/libretro/parallel-gx2.git
synced 2026-11-07 04:25:58 -10:00
The recompiler thread looked for work every 10 ms, so a function the interpreter had just run waited 5 ms on average before its translation began, and every queued address could allocate inside std::queue. Its queue is now a fixed retro_spsc ring with an eventcount (PPCRecompilerWorkQueue): a push wakes the thread at once, the thread pops without the recompiler's spinlock, and a full queue refuses the push so the address stays unvisited and is offered again later. Loading the Vulkan pipeline cache napped 10 ms whenever 50 pipelines were queued and again while the last ones compiled, which held a warm driver cache to 50 pipelines per 10 ms. The GPU thread now sleeps on an eventcount (LatteGpuWake) that the compile threads notify after each pipeline and that a pause request or a stop also notify, so it refills the queue as soon as there is room and still answers a context loss at once. The pipeline cache's save thread keeps its 15 s debounce but sleeps on an eventcount that the renderer's destruction notifies, instead of looking every 250 ms. The CPU timer's TSC calibration measured for three seconds and the title start waited for it, which in RetroArch is every boot. Both clocks are read back to back, so 25 ms already gives about one part in 10^5: the first estimate is published then and refined at 200 ms and 3 s by the same measurement. The rate only divides elapsed ticks, so a refinement changes no time already counted. The title start waits on an eventcount instead of a 10 ms poll. Audio goes to the frontend straight out of the ring buffer (Peek/Consume) and AX's blocks are converted straight into it (Reserve/Commit), so the per-frame copy into a 192 KiB flush buffer, the pull buffer and the conversion vector are gone. The ring moves to LibretroAudioRing.h. The frame gate and the frame handoff between the GPU thread and retro_run are atomics and eventcounts in place of two mutexes and condition variables, with the same predicates and the same timeout. retro_spsc is synced from RetroArch's libretro-common. test/handoff checks the work queue (every address once and in order from three serialised pushers, wake-up from a parked consumer, the bound, the stop), the GPU wake, and the audio ring (whole-frame spans across the wrap for 2 and 6 channels, a producer and a consumer thread streaming), plain, under TSan and under ASan/UBSan, in both CIs.