Skip to content

SNES (supafaust) crashes on launch on Smart Pro S due to thread affinity assuming all CPUs are online #785

Description

@carroarmato0

On the Smart Pro S (tg5050), opening a SNES game causes minarch to crash immediately with terminate called after throwing an instance of 'Mednafen::MDFN_Error'. The game never starts.

The cause is in skeleton/EXTRAS/Emus/tg5050/SUPA.pak/default.cfg. When tg5050 support was added in 89158fe, the affinity values were copied verbatim from the tg5040 config:

-supafaust_thread_affinity_emu = 0x3
-supafaust_thread_affinity_ppu = 0xc

On tg5040, CPUs 0-3 are all online at idle, so this works fine. On tg5050, the kernel only keeps CPUs 0, 1, and 4 online at idle due to CPU hotplugging. The value 0xc targets CPUs 2 and 3, which are offline at game launch time. When supafaust calls pthread_setaffinity_np with offline CPUs in the mask, it gets EINVAL, throws MDFN_Error from inside retro_load_game, and the frontend crashes.

The crash happens during game load, before the emulation loop starts, so the CPU governor hasn't had a chance to respond to any load and bring those cores online.

There are a few ways to approach this:

One option is to simply set supafaust_thread_affinity_ppu = 0x0 for tg5050, which disables the affinity feature and lets the OS schedule the PPU thread freely. The affinity settings are a performance hint, not a requirement, so this is safe and eliminates the problem entirely.

Another option is to pin to a CPU that is reliably online on tg5050, like CPU 4 (0x10). This preserves the intent of separating the emu and PPU threads onto different cores. The risk is that hotplugging is nondeterministic and CPU 4 could theoretically also be offline at the exact moment the affinity call happens, making this only probabilistically better rather than a real fix.

A third option is to fix supafaust's Thread_SetAffinity to not throw when pthread_setaffinity_np fails, and instead log and continue. That would make the frontend resilient to any affinity configuration, but it's a change in the core rather than the config.

Worth discussing which direction makes most sense before committing to a fix.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions