Cross-platform spin lock implementation.

This commit is contained in:
Skyth 2024-12-16 00:03:40 +03:00
parent d68e88314f
commit 58c8ed45e0

View file

@ -695,16 +695,23 @@ void RtlRaiseException_x()
void KfReleaseSpinLock(uint32_t* spinLock) void KfReleaseSpinLock(uint32_t* spinLock)
{ {
InterlockedExchange((volatile long*)spinLock, 0); std::atomic_ref spinLockRef(*spinLock);
spinLockRef = 0;
} }
void KfAcquireSpinLock(uint32_t* spinLock) 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(); std::this_thread::yield();
} }
}
uint64_t KeQueryPerformanceFrequency() uint64_t KeQueryPerformanceFrequency()
{ {
@ -735,16 +742,23 @@ void VdGetSystemCommandBuffer()
void KeReleaseSpinLockFromRaisedIrql(uint32_t* spinLock) void KeReleaseSpinLockFromRaisedIrql(uint32_t* spinLock)
{ {
InterlockedExchange((volatile long*)spinLock, 0); std::atomic_ref spinLockRef(*spinLock);
spinLockRef = 0;
} }
void KeAcquireSpinLockAtRaisedIrql(uint32_t* spinLock) 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(); std::this_thread::yield();
} }
}
uint32_t KiApcNormalRoutineNop() uint32_t KiApcNormalRoutineNop()
{ {