Skip to content
Snippets Groups Projects
Commit ae1aa461 authored by Graham Madarasz (Graham)'s avatar Graham Madarasz (Graham)
Browse files

Attempt at a faster ThreadSafeRefCount class

parent 93eaccae
No related branches found
No related tags found
No related merge requests found
......@@ -164,14 +164,20 @@ template <typename Type> class LLAtomic32
~LLAtomic32<Type>() {};
operator const Type() { apr_uint32_t data = apr_atomic_read32(&mData); return Type(data); }
Type CurrentValue() const { apr_uint32_t data = apr_atomic_read32(const_cast< volatile apr_uint32_t* >(&mData)); return Type(data); }
Type operator =(const Type& x) { apr_atomic_set32(&mData, apr_uint32_t(x)); return Type(mData); }
void operator -=(Type x) { apr_atomic_sub32(&mData, apr_uint32_t(x)); }
void operator +=(Type x) { apr_atomic_add32(&mData, apr_uint32_t(x)); }
Type operator ++(int) { return apr_atomic_inc32(&mData); } // Type++
Type operator --(int) { return apr_atomic_dec32(&mData); } // approximately --Type (0 if final is 0, non-zero otherwise)
Type operator ++() { return apr_atomic_inc32(&mData); } // Type++
Type operator --() { return apr_atomic_dec32(&mData); } // approximately --Type (0 if final is 0, non-zero otherwise)
private:
apr_uint32_t mData;
volatile apr_uint32_t mData;
};
typedef LLAtomic32<U32> LLAtomicU32;
......
......@@ -495,15 +495,7 @@ LLThreadSafeRefCount::LLThreadSafeRefCount() :
LLThreadSafeRefCount::LLThreadSafeRefCount(const LLThreadSafeRefCount& src)
{
if (sMutex)
{
sMutex->lock();
}
mRef = 0;
if (sMutex)
{
sMutex->unlock();
}
}
LLThreadSafeRefCount::~LLThreadSafeRefCount()
......
......@@ -241,47 +241,43 @@ class LL_COMMON_API LLThreadSafeRefCount
LLThreadSafeRefCount(const LLThreadSafeRefCount&);
LLThreadSafeRefCount& operator=(const LLThreadSafeRefCount& ref)
{
if (sMutex)
{
sMutex->lock();
}
mRef = 0;
if (sMutex)
{
sMutex->unlock();
}
return *this;
}
void ref()
{
if (sMutex) sMutex->lock();
mRef++;
if (sMutex) sMutex->unlock();
}
S32 unref()
{
llassert(mRef >= 1);
if (sMutex) sMutex->lock();
S32 res = --mRef;
if (sMutex) sMutex->unlock();
if (0 == res)
llassert(mRef >= 1);
bool time_to_die = (mRef == 1);
if (time_to_die)
{
delete this;
if (sMutex) sMutex->lock();
// Looks redundant, but is very much not
// We need to check again once we've acquired the lock
// so that two threads who get into the if in parallel
// don't both attempt to the delete.
//
if (mRef == 1)
delete this;
mRef--;
if (sMutex) sMutex->unlock();
return 0;
}
return res;
}
return --mRef;
}
S32 getNumRefs() const
{
return mRef;
const S32 currentVal = mRef.CurrentValue();
return currentVal;
}
private:
S32 mRef;
LLAtomic32< S32 > mRef;
};
//============================================================================
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment