summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBehdad Esfahbod <behdad@behdad.org>2013-01-10 01:17:02 -0600
committerBehdad Esfahbod <behdad@behdad.org>2013-01-10 01:17:46 -0600
commit98efed3bcafc92b573b193b5b38039aa717617d3 (patch)
tree75fcb7b3cb287dec325f863647226a563fc8001d
parent8e8a99ae8a1c2e56c42093bee577d6de66248366 (diff)
Add atomic ops for Solaris
Patch from Raimund Steger.
-rw-r--r--configure.ac22
-rw-r--r--src/fcatomic.h12
2 files changed, 32 insertions, 2 deletions
diff --git a/configure.ac b/configure.ac
index 5511077..ef222be 100644
--- a/configure.ac
+++ b/configure.ac
@@ -592,8 +592,26 @@ if $fc_cv_have_intel_atomic_primitives; then
AC_DEFINE(HAVE_INTEL_ATOMIC_PRIMITIVES, 1, [Have Intel __sync_* atomic primitives])
fi
-AC_CHECK_HEADERS(sched.h)
-AC_CHECK_FUNCS(sched_yield)
+AC_CACHE_CHECK([for Solaris atomic operations], fc_cv_have_solaris_atomic_ops, [
+ fc_cv_have_solaris_atomic_ops=false
+ AC_TRY_LINK([
+ #include <atomic.h>
+ /* This requires Solaris Studio 12.2 or newer: */
+ #include <mbarrier.h>
+ void memory_barrier (void) { __machine_rw_barrier (); }
+ int atomic_add (volatile unsigned *i) { return atomic_add_int_nv (i, 1); }
+ void *atomic_ptr_cmpxchg (volatile void **target, void *cmp, void *newval) { return atomic_cas_ptr (target, cmp, newval); }
+ ], [], fc_cv_have_solaris_atomic_ops=true
+ )
+])
+if $fc_cv_have_solaris_atomic_ops; then
+ AC_DEFINE(HAVE_SOLARIS_ATOMIC_OPS, 1, [Have Solaris __machine_*_barrier and atomic_* operations])
+fi
+
+if test "$os_win32" = no && ! $have_pthread; then
+ AC_CHECK_HEADERS(sched.h)
+ AC_SEARCH_LIBS(sched_yield,rt,AC_DEFINE(HAVE_SCHED_YIELD, 1, [Have sched_yield]))
+fi
have_pthread=false
if test "$os_win32" = no; then
diff --git a/src/fcatomic.h b/src/fcatomic.h
index 72ae372..a764311 100644
--- a/src/fcatomic.h
+++ b/src/fcatomic.h
@@ -87,6 +87,18 @@ typedef int fc_atomic_int_t;
#define fc_atomic_ptr_cmpexch(P,O,N) __sync_bool_compare_and_swap ((P), (O), (N))
+#elif !defined(FC_NO_MT) && defined(HAVE_SOLARIS_ATOMIC_OPS)
+
+#include <atomic.h>
+#include <mbarrier.h>
+
+typedef unsigned int fc_atomic_int_t;
+#define fc_atomic_int_add(AI, V) ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V))
+
+#define fc_atomic_ptr_get(P) ( ({__machine_rw_barrier ();}), (void *) *(P))
+#define fc_atomic_ptr_cmpexch(P,O,N) ( ({__machine_rw_barrier ();}), atomic_cas_ptr ((P), (O), (N)) == (void *) (O) ? FcTrue : FcFalse)
+
+
#elif !defined(FC_NO_MT)
#define FC_ATOMIC_INT_NIL 1 /* Warn that fallback implementation is in use. */