Detect and use atomic integer operations for RefObject reference counter.

Note that GCC supports them on specific architectures, on some platforms -march=... must be set in CFLAGS.


git-svn-id: http://voip.null.ro/svn/yate@4682 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
paulc 2011-11-07 17:10:32 +00:00
parent b1b9bfb4b7
commit 55e3261c5f
5 changed files with 85 additions and 2 deletions

View File

@ -291,6 +291,29 @@ esac
AC_MSG_RESULT([$want_inline])
AC_SUBST(INLINE_FLAGS)
# Check for atomic integer operations
ATOMIC_OPS=""
AC_ARG_ENABLE(atomics,AC_HELP_STRING([--enable-atomics],[Enable atomic integer operations (default: yes)]),want_atomics=$enableval,want_atomics=yes)
if [[ "x$want_atomics" != "xno" ]]; then
AC_MSG_CHECKING([whether to use atomic integer operations])
AC_LANG_SAVE
AC_LANG_C
SAVE_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Wall -Werror"
AC_TRY_LINK([],[
int i = 0;
int j = __sync_add_and_fetch(&i,1);
return __sync_fetch_and_sub(&j,1);
],
ATOMIC_OPS="-DATOMIC_OPS",
want_atomics="no (missing -march ?)"
)
CFLAGS="$SAVE_CFLAGS"
AC_LANG_RESTORE
AC_MSG_RESULT([$want_atomics])
fi
AC_SUBST(ATOMIC_OPS)
FDSIZE_HACK=""
AC_ARG_WITH(fdsize,AC_HELP_STRING([--with-fdsize=NNNN],[set FD_SIZE to NNNN (default 8192)]),[ac_cv_use_fdsize=$withval],[ac_cv_use_fdsize=8192])
if [[ "x$ac_cv_use_fdsize" != "xno" ]]; then

View File

@ -100,6 +100,9 @@ Mutex.o: @srcdir@/Mutex.cpp $(MKDEPS) $(CINC)
Thread.o: @srcdir@/Thread.cpp $(MKDEPS) $(CINC)
$(COMPILE) @THREAD_KILL@ @HAVE_PRCTL@ -c $<
TelEngine.o: @srcdir@/TelEngine.cpp $(MKDEPS) $(CINC)
$(COMPILE) @ATOMIC_OPS@ -c $<
Client.o: @srcdir@/Client.cpp $(MKDEPS) $(CLINC)
$(COMPILE) -c $<

View File

@ -627,12 +627,16 @@ void GenObject::destruct()
}
#ifndef ATOMIC_OPS
static MutexPool s_refMutex(REFOBJECT_MUTEX_COUNT,false,"RefObject");
#endif
RefObject::RefObject()
: m_refcount(1), m_mutex(0)
{
#ifndef ATOMIC_OPS
m_mutex = s_refMutex.mutex(this);
#endif
}
RefObject::~RefObject()
@ -653,21 +657,45 @@ void RefObject::destruct()
bool RefObject::ref()
{
#ifdef ATOMIC_OPS
#ifdef _WINDOWS
if (InterlockedIncrement((LONG*)&m_refcount) > 1)
return true;
InterlockedDecrement((LONG*)&m_refcount);
#else
if (__sync_add_and_fetch(&m_refcount,1) > 1)
return true;
__sync_sub_and_fetch(&m_refcount,1);
#endif
#else
Lock lock(m_mutex);
if (m_refcount > 0) {
++m_refcount;
return true;
}
#endif
return false;
}
bool RefObject::deref()
{
#ifdef ATOMIC_OPS
#ifdef _WINDOWS
int i = InterlockedDecrement((LONG*)&m_refcount) + 1;
if (i <= 0)
InterlockedIncrement((LONG*)&m_refcount);
#else
int i = __sync_fetch_and_sub(&m_refcount,1);
if (i <= 0)
__sync_fetch_and_add(&m_refcount,1);
#endif
#else
m_mutex->lock();
int i = m_refcount;
if (i > 0)
--m_refcount;
m_mutex->unlock();
#endif
if (i == 1)
zeroRefs();
else if (i <= 0)
@ -683,18 +711,40 @@ void RefObject::zeroRefs()
bool RefObject::resurrect()
{
#ifdef ATOMIC_OPS
#ifdef _WINDOWS
if (InterlockedIncrement((LONG*)&m_refcount) == 1)
return true;
InterlockedDecrement((LONG*)&m_refcount);
return false;
#else
if (__sync_add_and_fetch(&m_refcount,1) == 1)
return true;
__sync_sub_and_fetch(&m_refcount,1);
return false;
#endif
#else
m_mutex->lock();
bool ret = (0 == m_refcount);
if (ret)
m_refcount = 1;
m_mutex->unlock();
return ret;
#endif
}
void RefObject::destroyed()
{
}
bool RefObject::efficientIncDec()
{
#ifdef ATOMIC_OPS
return true;
#else
return false;
#endif
}
void RefPointerBase::assign(RefObject* oldptr, RefObject* newptr, void* pointer)
{

View File

@ -49,7 +49,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=".,..,..\engine\regex,..\engine\tables"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBYATE_EXPORTS;__STDC__;_CRT_SECURE_NO_DEPRECATE;HAVE_DNS_NAPTR_DATA"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBYATE_EXPORTS;__STDC__;_CRT_SECURE_NO_DEPRECATE;ATOMIC_OPS;HAVE_DNS_NAPTR_DATA"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
@ -147,7 +147,7 @@
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories=".,..,..\engine\regex,..\engine\tables"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBYATE_EXPORTS;__STDC__;_CRT_SECURE_NO_DEPRECATE;HAVE_DNS_NAPTR_DATA"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBYATE_EXPORTS;__STDC__;_CRT_SECURE_NO_DEPRECATE;ATOMIC_OPS;HAVE_DNS_NAPTR_DATA"
StringPooling="true"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"

View File

@ -812,6 +812,13 @@ public:
*/
virtual void destruct();
/**
* Check if reference counter manipulations are efficient on this platform.
* If platform does not support atomic operations a mutex pool is used.
* @return True if refcount uses atomic integer operations
*/
static bool efficientIncDec();
protected:
/**
* This method is called when the reference count reaches zero after