Attempt at a faster ThreadSafeRefCount class
parent
93eaccae6f
commit
ae1aa461ea
|
|
@ -164,14 +164,20 @@ public:
|
|||
~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 @@ public:
|
|||
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;
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
|
|
|
|||
Loading…
Reference in New Issue