mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-26 12:48:39 +08:00
63b440efcd
* [HLE] Fix guest-thread sync and boot for Unreal Engine titles Silent Hill: The Short Message (and other UE titles) now boot the full engine thread graph instead of hanging early. Four related fixes: - pthread cond/mutex semantics: retain a signal raised with no waiter as pending, and key block/wake on the state's identity rather than a resolved address that could differ between lock and unlock. This ends the ~1.5M-call cond_wait busy-spin. - Warm HLE type initializers and force-JIT their methods on a host thread at Freeze(). A .cctor or first-time JIT running on a guest thread's hijacked stack fail-fasts the CLR as "Invalid Program: attempted to call a UnmanagedCallersOnly method from managed code". - Guest thread scheduling: pump after a wake so a readied thread actually runs, add a dispatcher thread for when every guest thread is parked, and make the pump-depth guard an atomic CAS. - Route mutex/rwlock lock/unlock off the non-blocking leaf-import fast path so a contended lock can deschedule its guest thread. Ported from the unreal-boot-fixes branch. * [HLE] Keep mutex/rwlock unlock on the leaf-import fast path The previous change routed all mutex/rwlock lock and unlock NIDs off the leaf fast path so a contended lock could deschedule its guest thread. But unlock never blocks, and taking it off the fast path made it slow enough that Demon's Souls' job workers livelocked in a guest spinlock (millions of mutex_unlock calls, no import progress, main thread stuck in sceKernelWaitEventFlag). Only *lock* needs to leave the leaf path. Restore the four unlock NIDs (mutex + rwlock) so guest spinlocks stay cheap, while lock/rd/wrlock remain off it for the blocking case Silent Hill needs. * [HLE] Gate pthread_mutex_lock guest-thread blocking (fixes Demon's Souls) Re-enabling cooperative deschedule on a contended pthread_mutex_lock regressed Demon's Souls: its job workers run on libSceFiber, and blocking a guest thread mid-fiber left sceFiberSwitch returning ESRCH followed by a null fiber-context deref (0xC0000005). Bisect confirmed the pthread change as the cause; the game reaches the same point as before it once the block is skipped. Gate the block behind SHARPEMU_MUTEX_LOCK_BLOCKING (off by default) so contended locks fall through to the synchronous host-thread wait. The rest of the pthread fixes (cond_wait pending signals, identity wake keys) are unaffected.