(feat) Retro Games - Native core thread safety, crash guards and input reliability enhancements - #1398
Draft
WizardOfYendor1 wants to merge 4 commits into
Draft
Conversation
Contributor
Author
|
I'm probably going to leave this in draft for a few days as I test more.... and get any feedback. |
❌ Checks FailedAll platform builds passed, but the test run did not. Tests ❌ 1 failed, 2048 passed Failing tests
|
…tency against its own low-latency request. Tweak to cut measured lag from 147ms to 115ms.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request
Summary
Yet more major improvements in input reliability and analog mode correctness for software rendered native cores, plus thread safety hardening and an N64 core caused crash fix(s).
During testing and debugging I noticed that when hammering on a button, for example on the 2600 asteroids game, it would sometimes drop button presses - not something you'd notice in ordinary play of other games that you're not button mashing to the max. Tracing it led to reworking the "latch" logic. Basically, SOME times keypress states were becoming "merged" within a polling window. Adding instrumentation logging, I measured about 14% got dropped as a result with my old, slow fingers. The host now records one pending press and one pending release per button and advances at most one transition per frame. After the changes, I remeasured over multiple asteroids mash sessions, ALL press/release pairs were delivered and acknowledged with none expiring (aka dropped).
That work also exposed a wrong assumption I had or understood wrong anyways. The host taks for granted that input was latched and read on the same thread. Generally true however in the case of the N64 emulator (for example), if I tinkered with the emulator settings with threaded rendering, buttons when dead. The mupen64plus-next with its threaded renderer, reads input from a thread the host had never latched on. I refactored the published input state to using atomics, so a read on one thread can't lose an acknowledgment written on another, and the host now counts off-thread reads so the next core that does this is identifiable rather than non deterministic behavior happening. Hardware rendering (which I'm testing also :-)), exposes quite nicely. I believe using atomics was the right way to go here...but boy I'm really pushing my C knowledge/expertise here.
More rounds of N64 tinkering hard crashed moonfin outright - seg faulting it, repeatedly.Root cause was a missing environment callback: cores call GET_CLEAR_ALL_THREAD_WAITS_CB without a null check, and we didn't provide it, giving one fixes the crash (this was SO FUN to hunt down!).
Another REAL gem of finding was that thread IDs were climbing about sixty times a second. I really don't know how I didn't notice this before but... turns out the render thread was getting a brand new thread name at roughly 60x per second(!). Chased it down with logging/debugger etc and it was attaching and detaching our otherwise detached render thread once per posted frame, creating a fresh thread every time. There's now one render thread, "moonfin.retro", attached once for the session and detached when the loop ends, so it just finds it already attached and uses it. That removes a per-frame thread registration from the render path; I would EXPECT it to have some positive impact on GC or memory headroom, more so on "lighter" hardware, but that's unmeasured. Regardless, this is more "right" IMO (the get geometry pattern).
Plus bunches of tests to cover all of this.
In a nutshell this took a lot of iterative work with diagnostic logging. The temporary counters, diagnostics etc came out before my commits, but I left the off thread input read "detector" and the unhanded environment logging. i.e. if a core asks for something we don't provide, log it. Helps future issues with cores easier to hunt down.
Type of Change
Platform
Testing
Live, interactive debugging/profiling with real devices (ADB). Playing real games, doing everything I could think of to push the devices over the edge.
Checklist