This patch adds support for spinlocks in Asterisk.

There are cases in Asterisk where it might be desirable to lock
a short critical code section but not incur the context switch
and yield penalty of a mutex or rwlock.  The primary spinlock
implementations execute exclusively in userspace and therefore
don't incur those penalties.  Spinlocks are NOT meant to be a
general replacement for mutexes.  They should be used only for
protecting short blocks of critical code such as simple compares
and assignments.  Operations that may block, hold a lock, or
cause the thread to give up it's timeslice should NEVER be
attempted in a spinlock.

The first use case for spinlocks is in astobj2 - internal_ao2_ref.
Currently the manipulation of the reference counter is done with
an ast_atomic_fetchadd_int which works fine.  When weak reference
containers are introduced however, there's an additional comparison
and assignment that'll need to be done while the lock is held.
A mutex would be way too expensive here, hence the spinlock.
Given that lock contention in this situation would be infrequent,
the overhead of the spinlock is only a few more machine instructions
than the current ast_atomic_fetchadd_int call.

ASTERISK-23553 #close
Review: https://reviewboard.asterisk.org/r/3405/


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/12@412976 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
George Joseph
2014-04-23 20:06:03 +00:00
parent 7ac2e15e77
commit 9400ad29ee
4 changed files with 523 additions and 1 deletions

56
configure vendored
View File

@@ -1,5 +1,5 @@
#! /bin/sh
# From configure.ac Revision: 406803 .
# From configure.ac Revision.
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for asterisk trunk.
#
@@ -15862,6 +15862,60 @@ else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTHREAD_MUTEX_ADAPTIVE_NP in pthread.h" >&5
$as_echo_n "checking for PTHREAD_MUTEX_ADAPTIVE_NP in pthread.h... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <pthread.h>
int
main ()
{
int a = PTHREAD_MUTEX_ADAPTIVE_NP;
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
$as_echo "#define HAVE_PTHREAD_MUTEX_ADAPTIVE_NP 1" >>confdefs.h
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_spinlock_t in pthread.h" >&5
$as_echo_n "checking for pthread_spinlock_t in pthread.h... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <pthread.h>
int
main ()
{
pthread_spinlock_t spin;
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
$as_echo "#define HAVE_PTHREAD_SPINLOCK 1" >>confdefs.h
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext