diff --git a/src/dynarmic/common/spin_lock_arm64.cpp b/src/dynarmic/common/spin_lock_arm64.cpp index 77d306cc..36871449 100644 --- a/src/dynarmic/common/spin_lock_arm64.cpp +++ b/src/dynarmic/common/spin_lock_arm64.cpp @@ -38,8 +38,12 @@ namespace { struct SpinLockImpl { SpinLockImpl(); + void Initialize(); + oaknut::CodeBlock mem; oaknut::CodeGenerator code; + + bool initialized = false; void (*lock)(volatile int*); void (*unlock)(volatile int*); }; @@ -48,7 +52,9 @@ SpinLockImpl impl; SpinLockImpl::SpinLockImpl() : mem{4096} - , code{mem.ptr()} { + , code{mem.ptr()} {} + +void SpinLockImpl::Initialize() { mem.unprotect(); lock = code.ptr(); @@ -60,15 +66,23 @@ SpinLockImpl::SpinLockImpl() code.RET(); mem.protect(); + + initialized = true; } } // namespace void SpinLock::Lock() { + if (!impl.initialized) [[unlikely]] { + impl.Initialize(); + } impl.lock(&storage); } void SpinLock::Unlock() { + if (!impl.initialized) [[unlikely]] { + impl.Initialize(); + } impl.unlock(&storage); } diff --git a/src/dynarmic/common/spin_lock_x64.cpp b/src/dynarmic/common/spin_lock_x64.cpp index 0f849931..9f0daa63 100644 --- a/src/dynarmic/common/spin_lock_x64.cpp +++ b/src/dynarmic/common/spin_lock_x64.cpp @@ -34,16 +34,18 @@ void EmitSpinLockUnlock(Xbyak::CodeGenerator& code, Xbyak::Reg64 ptr, Xbyak::Reg namespace { struct SpinLockImpl { - SpinLockImpl(); + void Initialize(); Xbyak::CodeGenerator code; + + bool initialized = false; void (*lock)(volatile int*); void (*unlock)(volatile int*); }; SpinLockImpl impl; -SpinLockImpl::SpinLockImpl() { +void SpinLockImpl::Initialize() { const Xbyak::Reg64 ABI_PARAM1 = Backend::X64::HostLocToReg64(Backend::X64::ABI_PARAM1); code.align(); @@ -55,15 +57,23 @@ SpinLockImpl::SpinLockImpl() { unlock = code.getCurr(); EmitSpinLockUnlock(code, ABI_PARAM1, code.eax); code.ret(); + + initialized = true; } } // namespace void SpinLock::Lock() { + if (!impl.initialized) [[unlikely]] { + impl.Initialize(); + } impl.lock(&storage); } void SpinLock::Unlock() { + if (!impl.initialized) [[unlikely]] { + impl.Initialize(); + } impl.unlock(&storage); }