From 0ea66ea0d868c59dcc7c346437b1455dc347422b Mon Sep 17 00:00:00 2001 From: Anthony Miles Date: Fri, 19 Jul 2019 18:42:59 +1200 Subject: [PATCH] Avoid tight loop in LockFS. Fixes Prince of Persia 2 slowdown during loading screen --- src/core/kernel/support/EmuFS.cpp | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/core/kernel/support/EmuFS.cpp b/src/core/kernel/support/EmuFS.cpp index c193edeaa..ad6e54b6e 100644 --- a/src/core/kernel/support/EmuFS.cpp +++ b/src/core/kernel/support/EmuFS.cpp @@ -125,15 +125,23 @@ uint32_t fs_lock = 0; __declspec(naked) void LockFS() { __asm { - pushfd - pushad - spinlock : - mov eax, 1 - xchg eax, fs_lock - test eax, eax - jnz spinlock - popad - popfd + // Backup Registers + pushfd + pushad + + // Spin until we can aquire the lock + spinlock : + call SwitchToThread // Give other threads chance to run, prevents hogging entire timeslice waiting for spinlock + // We do this here loop because SwitchToThread will overwrite eax, so it cannot go below + // It's not worth wasting the extra cycles of pushing/popping eax to the stack around this call + mov eax, 1 + xchg eax, fs_lock + test eax, eax + jnz spinlock + + // Restore registers and return + popad + popfd ret } }