summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordormando <dormando@rydia.net>2012-01-25 22:49:21 -0800
committerdormando <dormando@rydia.net>2012-01-25 22:56:02 -0800
commitde1f30c5d5f1d194564123d23f8b1180be21962a (patch)
treed2066251e93275506601a4b10de049f7f43d580f
parent85db132d127a42ccc2bcdef447813fa8895307ae (diff)
downloadmemcached-de1f30c5d5f1d194564123d23f8b1180be21962a.tar.gz
properly detect GCC atomics
I was naive. GCC atomics were added in 4.1.2, and not easily detectable without configure tests. 32bit platforms, centos5, etc.
-rw-r--r--configure.ac14
-rw-r--r--thread.c10
2 files changed, 19 insertions, 5 deletions
diff --git a/configure.ac b/configure.ac
index fdb385b..31f1f9d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -454,6 +454,20 @@ fi
AC_C_ALIGNMENT
+dnl Check for our specific usage of GCC atomics.
+dnl These were added in 4.1.2, but 32bit OS's may lack shorts and 4.1.2
+dnl lacks testable defines.
+have_gcc_atomics=no
+AC_MSG_CHECKING(for GCC atomics)
+AC_TRY_LINK([],[
+ unsigned short a;
+ unsigned short b;
+ b = __sync_add_and_fetch(&a, 1);
+ b = __sync_sub_and_fetch(&a, 2);
+ ],[have_gcc_atomics=yes
+ AC_DEFINE(HAVE_GCC_ATOMICS, 1, [GCC Atomics available])])
+AC_MSG_RESULT($have_gcc_atomics)
+
dnl Check for the requirements for running memcached with less privileges
dnl than the default privilege set. On Solaris we need setppriv and priv.h
dnl If you want to add support for other platforms you should check for
diff --git a/thread.c b/thread.c
index 5735376..698ce73 100644
--- a/thread.c
+++ b/thread.c
@@ -43,7 +43,7 @@ pthread_mutex_t cache_lock;
/* Connection lock around accepting new connections */
pthread_mutex_t conn_lock = PTHREAD_MUTEX_INITIALIZER;
-#if !defined(__GNUC__) && !defined(__sun)
+#if !defined(HAVE_GCC_ATOMICS) && !defined(__sun)
pthread_mutex_t atomics_mutex = PTHREAD_MUTEX_INITIALIZER;
#endif
@@ -79,14 +79,14 @@ static pthread_cond_t init_cond;
static void thread_libevent_process(int fd, short which, void *arg);
inline unsigned short refcount_incr(unsigned short *refcount) {
-#ifdef __GNUC__
+#ifdef HAVE_GCC_ATOMICS
return __sync_add_and_fetch(refcount, 1);
#elif defined(__sun)
return atomic_inc_ushort_nv(refcount);
#else
unsigned short res;
mutex_lock(&atomics_mutex);
- *refcount++;
+ (*refcount)++;
res = *refcount;
pthread_mutex_unlock(&atomics_mutex);
return res;
@@ -94,14 +94,14 @@ inline unsigned short refcount_incr(unsigned short *refcount) {
}
inline unsigned short refcount_decr(unsigned short *refcount) {
-#ifdef __GNUC__
+#ifdef HAVE_GCC_ATOMICS
return __sync_sub_and_fetch(refcount, 1);
#elif defined(__sun)
return atomic_dec_ushort_nv(refcount);
#else
unsigned short res;
mutex_lock(&atomics_mutex);
- *refcount--;
+ (*refcount)--;
res = *refcount;
pthread_mutex_unlock(&atomics_mutex);
return res;