From 58c8ed45e083d5ffd035937d6d4c17dda847d0d4 Mon Sep 17 00:00:00 2001 From: Skyth <19259897+blueskythlikesclouds@users.noreply.github.com> Date: Mon, 16 Dec 2024 00:03:40 +0300 Subject: [PATCH] Cross-platform spin lock implementation. --- UnleashedRecomp/kernel/imports.cpp | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/UnleashedRecomp/kernel/imports.cpp b/UnleashedRecomp/kernel/imports.cpp index ebbf7e4e..d1d02103 100644 --- a/UnleashedRecomp/kernel/imports.cpp +++ b/UnleashedRecomp/kernel/imports.cpp @@ -695,15 +695,22 @@ void RtlRaiseException_x() void KfReleaseSpinLock(uint32_t* spinLock) { - InterlockedExchange((volatile long*)spinLock, 0); + std::atomic_ref spinLockRef(*spinLock); + spinLockRef = 0; } void KfAcquireSpinLock(uint32_t* spinLock) { - const auto ctx = GetPPCContext(); + std::atomic_ref spinLockRef(*spinLock); + + while (true) + { + uint32_t expected = 0; + if (spinLockRef.compare_exchange_weak(expected, g_ppcContext->r13.u32)) + break; - while (InterlockedCompareExchange((volatile long*)spinLock, ByteSwap(*(uint32_t*)(g_memory.Translate(ctx->r13.u32 + 0x110))), 0) != 0) std::this_thread::yield(); + } } uint64_t KeQueryPerformanceFrequency() @@ -735,15 +742,22 @@ void VdGetSystemCommandBuffer() void KeReleaseSpinLockFromRaisedIrql(uint32_t* spinLock) { - InterlockedExchange((volatile long*)spinLock, 0); + std::atomic_ref spinLockRef(*spinLock); + spinLockRef = 0; } void KeAcquireSpinLockAtRaisedIrql(uint32_t* spinLock) { - const auto ctx = GetPPCContext(); + std::atomic_ref spinLockRef(*spinLock); + + while (true) + { + uint32_t expected = 0; + if (spinLockRef.compare_exchange_weak(expected, g_ppcContext->r13.u32)) + break; - while (InterlockedCompareExchange((volatile long*)spinLock, ByteSwap(*(uint32_t*)(g_memory.Translate(ctx->r13.u32 + 0x110))), 0) != 0) std::this_thread::yield(); + } } uint32_t KiApcNormalRoutineNop()