Skip to content

Linux support: guest-thread scheduling, pthread sync, and GC fail-fast fixes#92

Closed
Spooks4576 wants to merge 5 commits into
par274:mainfrom
Spooks4576:main
Closed

Linux support: guest-thread scheduling, pthread sync, and GC fail-fast fixes#92
Spooks4576 wants to merge 5 commits into
par274:mainfrom
Spooks4576:main

Conversation

@Spooks4576

Copy link
Copy Markdown

Brings the emulator up on Linux and fixes several runtime crashes that
blocked titles from reaching the Vulkan presenter.

Linux platform support

  • Replace the kernel32-based memory backend with an mmap/POSIX path so
    PhysicalVirtualMemory works off Windows.
  • Route the Win32 host procedure lookups through Linux thunks, and
    short-circuit the kernel32-only native worker off Windows.
  • Unix signal handling for guest access faults.

Guest-thread scheduling and pthread semantics

  • Fix mutex identity so an object reachable through aliased addresses
    resolves to one state, and correct rwlock/condvar wake-key handling.
  • PlayGo open and assorted HLE export fixes.

GC fail-fast on guest threads

Guest threads execute managed HLE on a hijacked stack that the GC cannot
walk, so any collection landing mid-export fail-fasts the runtime with a
misleading "attempted to call an UnmanagedCallersOnly method from managed
code" error.

TryReadWideCString was the reliable trigger: it allocated its 1 MiB
ceiling up front, putting a 2 MB array on the Large Object Heap for every
vswprintf call, and an LOH allocation forces a GC. It now measures the
string first and allocates exactly its length. Type initializers for the
Silk.NET and framework assemblies are also warmed on the host thread, so a
guest thread is never the first to run a .cctor.

Presenter

vkQueuePresentKHR is the only throttle on the window loop, so a
RenderCore with nothing to present spun the callback flat out, pegging a
core and starving the guest threads it was waiting on. It now yields.

- Dispatch Ready guest threads promptly: pump on wake and add a 1ms
  dispatcher; make the pump reentrancy guard an interlocked CAS.
- cond_wait now fully releases recursive mutexes and restores depth.
- rwlock compat writers are exclusive with writer preference.
- Self-lock on NORMAL/ADAPTIVE_NP mutexes blocks instead of nesting.
- scePlayGoOpen no longer fails when the title ships no PlayGo metadata.
- Report sync-object state and per-thread wait keys in stall dumps.
TryReadWideCString allocated its 1 MiB ceiling up front, putting a 2 MB
array on the LOH for every vswprintf call. The GC that forced could not
walk a guest thread's hijacked stack, so the runtime fail-fasted with a
misleading "UnmanagedCallersOnly" error. Measure the string first, then
allocate exactly its length.

Warm Silk.NET and framework type initializers on the host thread so a
guest thread is never the first to run a .cctor.

Yield in the presenter when there is nothing to present: vkQueuePresentKHR
is the only throttle on the window loop, so an empty RenderCore pegged a
core and starved the guest threads it was waiting on.

Also trace why a presentation is withheld, to chase the blank window.
The upstream native worker calls kernel32 through GetModuleHandle/
GetProcAddress, which this fork renamed to WindowsGetModuleHandle/
WindowsGetProcAddress for the Linux port. Point it at the renamed
imports and short-circuit the lookup off Windows, where kernel32 is
unresolvable.
@j92580498-max

Copy link
Copy Markdown
Contributor

Could you post a screenshot of it working on Linux?

@Spooks4576

Copy link
Copy Markdown
Author

Could you post a screenshot of it working on Linux?

i will do so soon right now this is a step in the right direction towards Linux support
if a working game actually works on Linux vs windows remains to be seen

@par274

par274 commented Jul 12, 2026

Copy link
Copy Markdown
Owner

Testing Windows, broke Dreaming Sarah & Demon's Souls;

resim resim

@Spooks4576

Copy link
Copy Markdown
Author

Testing Windows, broke Dreaming Sarah & Demon's Souls;

resim resim

yeah im aware my build has issues with this now
however i tested upstream without my changes and this broke without my changes so unless im testing the wrong thing

@Spooks4576

Copy link
Copy Markdown
Author

Build Broke Something will wait on the other Linux Support Branch PR before giving my other changes

@Spooks4576 Spooks4576 closed this Jul 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants