{
public:
AtomicRefCount();
int increment();
int decrement();
void reset();
private:
AtomicRefCount& operator=( const AtomicRefCount& );volatile int m_count;
Mutex m_lock;
};
#include "atomicrefcount.h"
#if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
# include <windows.h>
#elif defined( __APPLE__ )
# include <libkern/OSAtomic.h>
#elif defined( HAVE_GCC_ATOMIC_BUILTINS )
// Use intrinsic functions - no #include required.
#else
# include "mutexguard.h"
#endif
#ifdef _WIN32_WCE
# include <winbase.h>
#endif
AtomicRefCount::AtomicRefCount()
: m_count( 0 )
{
}
int AtomicRefCount::increment()
{
#if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
return (int) ::InterlockedIncrement( (volatile LONG*)&m_count );
#elif defined( __APPLE__ )
return (int) OSAtomicIncrement32Barrier( (volatile int32_t*)&m_count );
#elif defined( HAVE_GCC_ATOMIC_BUILTINS )
// Use the gcc intrinsic for atomic increment if supported.
return (int) __sync_add_and_fetch( &m_count, 1 );
#else
// Fallback to using a lock
MutexGuard m( m_lock );
return ++m_count;
#endif
}
int AtomicRefCount::decrement()
{
#if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
return (int) ::InterlockedDecrement( (volatile LONG*)&m_count );
#elif defined( __APPLE__ )
return (int) OSAtomicDecrement32Barrier( (volatile int32_t*)&m_count );
#elif defined( HAVE_GCC_ATOMIC_BUILTINS )
// Use the gcc intrinsic for atomic decrement if supported.
return (int) __sync_sub_and_fetch( &m_count, 1 );
#else
// Fallback to using a lock
MutexGuard m( m_lock );
return --m_count;
#endif
}
void AtomicRefCount::reset()
{
#if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
::InterlockedExchange( (volatile LONG*)&m_count, (volatile LONG)0 );
#elif defined( __APPLE__ )
OSAtomicAnd32Barrier( (int32_t)0, (volatile int32_t*)&m_count );
#elif defined( HAVE_GCC_ATOMIC_BUILTINS )
// Use the gcc intrinsic for atomic decrement if supported.
__sync_fetch_and_and( &m_count, 0 );
#else
// Fallback to using a lock
MutexGuard m( m_lock );
m_count = 0;
#endif
}