Cross-platform reference counting.

This commit is contained in:
Skyth 2024-12-16 00:23:11 +03:00
parent 58c8ed45e0
commit bc3843fda7
3 changed files with 21 additions and 7 deletions

View file

@ -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<LONG*>(&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<LONG*>(&RefCountAndLength), decrementedValue, originalValue) != originalValue);
} while (!atomicRef.compare_exchange_weak(originalValue, decrementedValue));
if (RefCountAndLength == 0)
__HH_FREE(this);

View file

@ -28,22 +28,26 @@ namespace boost
void add_ref()
{
std::atomic_ref useCount(use_count_.value);
be<uint32_t> 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<uint32_t> 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<uint32_t> 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)
{

View file

@ -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<LONG*>(&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<LONG*>(&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.