From bc3843fda7b1afd17beb25f9735df2354ee78e89 Mon Sep 17 00:00:00 2001 From: Skyth <19259897+blueskythlikesclouds@users.noreply.github.com> Date: Mon, 16 Dec 2024 00:23:11 +0300 Subject: [PATCH] Cross-platform reference counting. --- .../api/Hedgehog/Base/Type/detail/hhStringHolder.inl | 8 ++++++-- UnleashedRecomp/api/boost/smart_ptr/shared_ptr.h | 12 +++++++++--- UnleashedRecomp/gpu/video.h | 8 ++++++-- 3 files changed, 21 insertions(+), 7 deletions(-) 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.