[Cpu] Give guest execution threads a 64 MiB host stack for nested continuations

Every guest call that blocks in an HLE import resumes through a managed
continuation frame, so a guest thread that blocks deep inside its own call
tree nests host frames instead of unwinding them. Demon's Souls' render
thread overflowed the default thread stack within a minute of reaching its
main loop.

Guest execution threads now reserve 64 MiB. The reservation is virtual, so a
generous stack costs nothing until it is touched.
This commit is contained in:
kuba 2026-09-27 01:01:05 +02:00
parent 4d65ff6d51
commit e99fcb9651
1 changed files with 9 additions and 1 deletions

View File

@ -608,9 +608,17 @@ public sealed unsafe partial class DirectExecutionBackend : INativeCpuBackend, I
private Action? _work;
private volatile bool _stopping;
// Every guest call that blocks in an HLE import resumes through a managed
// continuation frame, so a guest thread that blocks deep inside its own call
// tree nests host frames rather than unwinding. Demon's Souls' render thread
// overflowed the default thread stack within a minute of reaching its main
// loop; the reservation is virtual, so a generous stack costs nothing until
// it is touched.
private const int GuestExecutionStackBytes = 64 * 1024 * 1024;
public GuestExecutionRunner(ulong guestThreadHandle, string name, ThreadPriority priority)
{
_thread = new Thread(() => ThreadMain(guestThreadHandle))
_thread = new Thread(() => ThreadMain(guestThreadHandle), GuestExecutionStackBytes)
{
IsBackground = true,
Name = $"SharpEmu-{name}",