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:
parent
b1b9bfb4b7
commit
55e3261c5f
23
configure.in
23
configure.in
|
@ -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
|
||||
|
|
|
@ -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 $<
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue