diff --git a/UnleashedRecomp/api/Hedgehog/Base/Type/detail/hhStringHolder.inl b/UnleashedRecomp/api/Hedgehog/Base/Type/detail/hhStringHolder.inl index 5bd47552..521a21d1 100644 --- a/UnleashedRecomp/api/Hedgehog/Base/Type/detail/hhStringHolder.inl +++ b/UnleashedRecomp/api/Hedgehog/Base/Type/detail/hhStringHolder.inl @@ -44,22 +44,26 @@ namespace Hedgehog::Base inline void SStringHolder::AddRef() { + std::atomic_ref atomicRef(RefCountAndLength.value); + uint32_t originalValue, incrementedValue; do { originalValue = RefCountAndLength.value; incrementedValue = ByteSwap(ByteSwap(originalValue) + 1); - } while (InterlockedCompareExchange(reinterpret_cast(&RefCountAndLength), incrementedValue, originalValue) != originalValue); + } while (!atomicRef.compare_exchange_weak(originalValue, incrementedValue)); } inline void SStringHolder::Release() { + std::atomic_ref atomicRef(RefCountAndLength.value); + uint32_t originalValue, decrementedValue; do { originalValue = RefCountAndLength.value; decrementedValue = ByteSwap(ByteSwap(originalValue) - 1); - } while (InterlockedCompareExchange(reinterpret_cast(&RefCountAndLength), decrementedValue, originalValue) != originalValue); + } while (!atomicRef.compare_exchange_weak(originalValue, decrementedValue)); if (RefCountAndLength == 0) __HH_FREE(this); diff --git a/UnleashedRecomp/api/boost/smart_ptr/shared_ptr.h b/UnleashedRecomp/api/boost/smart_ptr/shared_ptr.h index adec62eb..9e62fdbb 100644 --- a/UnleashedRecomp/api/boost/smart_ptr/shared_ptr.h +++ b/UnleashedRecomp/api/boost/smart_ptr/shared_ptr.h @@ -28,22 +28,26 @@ namespace boost void add_ref() { + std::atomic_ref useCount(use_count_.value); + be original, incremented; do { original = use_count_; incremented = original + 1; - } while (InterlockedCompareExchange((unsigned long*)&use_count_, incremented.value, original.value) != original.value); + } while (!useCount.compare_exchange_weak(original.value, incremented.value)); } void release() { + std::atomic_ref useCount(use_count_.value); + be original, decremented; do { original = use_count_; decremented = original - 1; - } while (InterlockedCompareExchange((unsigned long*)&use_count_, decremented.value, original.value) != original.value); + } while (!useCount.compare_exchange_weak(original.value, decremented.value)); if (decremented == 0) { @@ -54,12 +58,14 @@ namespace boost void weak_release() { + std::atomic_ref weakCount(weak_count_.value); + be original, decremented; do { original = weak_count_; decremented = original - 1; - } while (InterlockedCompareExchange((unsigned long*)&weak_count_, decremented.value, original.value) != original.value); + } while (!weakCount.compare_exchange_weak(original.value, decremented.value)); if (decremented == 0) { diff --git a/UnleashedRecomp/gpu/video.h b/UnleashedRecomp/gpu/video.h index 34ddf886..7dd293c7 100644 --- a/UnleashedRecomp/gpu/video.h +++ b/UnleashedRecomp/gpu/video.h @@ -84,22 +84,26 @@ struct GuestResource void AddRef() { + std::atomic_ref atomicRef(refCount.value); + uint32_t originalValue, incrementedValue; do { originalValue = refCount.value; incrementedValue = ByteSwap(ByteSwap(originalValue) + 1); - } while (InterlockedCompareExchange(reinterpret_cast(&refCount), incrementedValue, originalValue) != originalValue); + } while (!atomicRef.compare_exchange_weak(originalValue, incrementedValue)); } void Release() { + std::atomic_ref atomicRef(refCount.value); + uint32_t originalValue, decrementedValue; do { originalValue = refCount.value; decrementedValue = ByteSwap(ByteSwap(originalValue) - 1); - } while (InterlockedCompareExchange(reinterpret_cast(&refCount), decrementedValue, originalValue) != originalValue); + } while (!atomicRef.compare_exchange_weak(originalValue, decrementedValue)); // Normally we are supposed to release here, so only use this // function when you know you won't be the one destructing it. 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()