mirror of
https://github.com/zeromq/libzmq.git
synced 2024-12-28 16:15:23 +08:00
Merge pull request #1330 from rodgert/master
Use GCC/Clang compiler intrinsics for atomic operations
This commit is contained in:
commit
153e0487de
24
acinclude.m4
24
acinclude.m4
@ -603,6 +603,26 @@ int main (int argc, char *argv [])
|
||||
)
|
||||
}])
|
||||
|
||||
dnl ################################################################################
|
||||
dnl # LIBZMQ_CHECK_ATOMIC_INSTRINSICS([action-if-found], [action-if-not-found]) #
|
||||
dnl # Check if compiler supoorts __atomic_Xxx intrinsics #
|
||||
dnl ################################################################################
|
||||
AC_DEFUN([LIBZMQ_CHECK_ATOMIC_INTRINSICS], [{
|
||||
AC_MSG_CHECKING(whether compiler supports __atomic_Xxx intrinsics)
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
|
||||
/* atomic intrinsics test */
|
||||
int v = 0;
|
||||
int main (int, char **)
|
||||
{
|
||||
int t = __atomic_add_fetch (&v, 1, __ATOMIC_ACQ_REL);
|
||||
return t;
|
||||
}
|
||||
])],
|
||||
[AC_MSG_RESULT(yes) ; libzmq_cv_has_atomic_instrisics="yes" ; $1],
|
||||
[AC_MSG_RESULT(no) ; libzmq_cv_has_atomic_instrisics="no" ; $2]
|
||||
)
|
||||
}])
|
||||
|
||||
dnl ################################################################################
|
||||
dnl # LIBZMQ_CHECK_SO_KEEPALIVE([action-if-found], [action-if-not-found]) #
|
||||
dnl # Check if SO_KEEPALIVE is supported #
|
||||
@ -764,7 +784,7 @@ kqueue();
|
||||
dnl ################################################################################
|
||||
dnl # LIBZMQ_CHECK_POLLER_EPOLL_RUN([action-if-found], [action-if-not-found]) #
|
||||
dnl # Checks epoll polling system can actually run #
|
||||
dnl # For cross-compile, only requires that epoll can link #
|
||||
dnl # For cross-compile, only requires that epoll can link #
|
||||
dnl ################################################################################
|
||||
AC_DEFUN([LIBZMQ_CHECK_POLLER_EPOLL], [{
|
||||
AC_RUN_IFELSE(
|
||||
@ -794,7 +814,7 @@ return(r < 0);
|
||||
)],
|
||||
[libzmq_cv_have_poller_epoll="yes" ; $1],
|
||||
[libzmq_cv_have_poller_epoll="no" ; $2])
|
||||
|
||||
|
||||
])
|
||||
}])
|
||||
|
||||
|
@ -479,6 +479,15 @@ AM_CONDITIONAL(ON_CYGWIN, test "x$libzmq_on_cygwin" = "xyes")
|
||||
AM_CONDITIONAL(ON_ANDROID, test "x$libzmq_on_android" = "xyes")
|
||||
AM_CONDITIONAL(ON_LINUX, test "x$libzmq_on_linux" = "xyes")
|
||||
|
||||
# Check for __atomic_Xxx compiler intrinsics
|
||||
AC_LANG_PUSH([C++])
|
||||
LIBZMQ_CHECK_ATOMIC_INTRINSICS([
|
||||
AC_DEFINE([ZMQ_HAVE_ATOMIC_INTRINSICS],
|
||||
[1],
|
||||
[Whether compiler has __atomic_Xxx intrinsics.])
|
||||
])
|
||||
AC_LANG_POP([C++])
|
||||
|
||||
# Checks for library functions.
|
||||
AC_TYPE_SIGNAL
|
||||
AC_CHECK_FUNCS(perror gettimeofday clock_gettime memset socket getifaddrs freeifaddrs fork posix_memalign)
|
||||
|
@ -25,6 +25,8 @@
|
||||
|
||||
#if defined ZMQ_FORCE_MUTEXES
|
||||
#define ZMQ_ATOMIC_COUNTER_MUTEX
|
||||
#elif defined ZMQ_HAVE_ATOMIC_INTRINSICS
|
||||
#define ZMQ_ATOMIC_INTRINSIC
|
||||
#elif (defined __i386__ || defined __x86_64__) && defined __GNUC__
|
||||
#define ZMQ_ATOMIC_COUNTER_X86
|
||||
#elif defined __ARM_ARCH_7A__ && defined __GNUC__
|
||||
@ -83,11 +85,13 @@ namespace zmq
|
||||
|
||||
#if defined ZMQ_ATOMIC_COUNTER_WINDOWS
|
||||
old_value = InterlockedExchangeAdd ((LONG*) &value, increment_);
|
||||
#elif defined ZMQ_ATOMIC_INTRINSIC
|
||||
old_value = __atomic_fetch_add(&value, increment_, __ATOMIC_ACQ_REL);
|
||||
#elif defined ZMQ_ATOMIC_COUNTER_ATOMIC_H
|
||||
integer_t new_value = atomic_add_32_nv (&value, increment_);
|
||||
old_value = new_value - increment_;
|
||||
#elif defined ZMQ_ATOMIC_COUNTER_TILE
|
||||
old_value = arch_atomic_add (&value, increment_);
|
||||
old_value = arch_atomic_add (&value, increment_);
|
||||
#elif defined ZMQ_ATOMIC_COUNTER_X86
|
||||
__asm__ volatile (
|
||||
"lock; xadd %0, %1 \n\t"
|
||||
@ -125,6 +129,9 @@ namespace zmq
|
||||
LONG delta = - ((LONG) decrement);
|
||||
integer_t old = InterlockedExchangeAdd ((LONG*) &value, delta);
|
||||
return old - decrement != 0;
|
||||
#elif defined ZMQ_ATOMIC_INTRINSIC
|
||||
integer_t nv = __atomic_sub_fetch(&value, decrement, __ATOMIC_ACQ_REL);
|
||||
return nv != 0;
|
||||
#elif defined ZMQ_ATOMIC_COUNTER_ATOMIC_H
|
||||
int32_t delta = - ((int32_t) decrement);
|
||||
integer_t nv = atomic_add_32_nv (&value, delta);
|
||||
|
@ -24,6 +24,8 @@
|
||||
|
||||
#if defined ZMQ_FORCE_MUTEXES
|
||||
#define ZMQ_ATOMIC_PTR_MUTEX
|
||||
#elif defined ZMQ_HAVE_ATOMIC_INTRINSICS
|
||||
#define ZMQ_ATOMIC_PTR_INTRINSIC
|
||||
#elif (defined __i386__ || defined __x86_64__) && defined __GNUC__
|
||||
#define ZMQ_ATOMIC_PTR_X86
|
||||
#elif defined __ARM_ARCH_7A__ && defined __GNUC__
|
||||
@ -82,6 +84,8 @@ namespace zmq
|
||||
{
|
||||
#if defined ZMQ_ATOMIC_PTR_WINDOWS
|
||||
return (T*) InterlockedExchangePointer ((PVOID*) &ptr, val_);
|
||||
#elif defined ZMQ_ATOMIC_PTR_INTRINSIC
|
||||
return (T*) __atomic_exchange_n (&ptr, val_, __ATOMIC_ACQ_REL);
|
||||
#elif defined ZMQ_ATOMIC_PTR_ATOMIC_H
|
||||
return (T*) atomic_swap_ptr (&ptr, val_);
|
||||
#elif defined ZMQ_ATOMIC_PTR_TILE
|
||||
@ -127,6 +131,11 @@ namespace zmq
|
||||
#if defined ZMQ_ATOMIC_PTR_WINDOWS
|
||||
return (T*) InterlockedCompareExchangePointer (
|
||||
(volatile PVOID*) &ptr, val_, cmp_);
|
||||
#elif defined ZMQ_ATOMIC_PTR_INTRINSIC
|
||||
T *old = cmp_;
|
||||
__atomic_compare_exchange_n (&ptr, (volatile T**) &old, val_, false,
|
||||
__ATOMIC_RELEASE, __ATOMIC_ACQUIRE);
|
||||
return old;
|
||||
#elif defined ZMQ_ATOMIC_PTR_ATOMIC_H
|
||||
return (T*) atomic_cas_ptr (&ptr, cmp_, val_);
|
||||
#elif defined ZMQ_ATOMIC_PTR_TILE
|
||||
|
Loading…
x
Reference in New Issue
Block a user