radioInterface: Atomically fetch and change underrun variable

Otherwise, it could happen that underrun events are lost:
TxLower (isUnderrun):	RxLower (pullBuffer):
read(underrun)
			read(underrun)
			write(underrun, |val) [maybe underrun becomes TRUE]
write(underrun, false)

Similary, it could happen the other direction if atomic was only applied
to isUnderrun:
TxLower (isUnderrun):	RxLower (pullBuffer):
			read(underrun) -> true
read(underrun)-> true
write(underrun, false)
			write(underrun, true|val) where val=false

So in here isUnderrun would return true twice while it should only
return one.

Change-Id: I684e0a5d2a9583a161d5a6593559b3a9e7cd57e3
diff --git a/configure.ac b/configure.ac
index fa9cf8d..350c77c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -190,29 +190,39 @@
 AC_DEFUN([CHECK_BUILTIN_SUPPORT], [
   AC_CACHE_CHECK(
     [whether ${CC} has $1 built-in],
-    [osmo_cv_cc_has_builtin], [
+    [osmo_cv_cc_has_$1], [
       AC_LINK_IFELSE([
         AC_LANG_PROGRAM([], [
-          __builtin_cpu_supports("sse");
+          $2
         ])
       ],
-      [AS_VAR_SET([osmo_cv_cc_has_builtin], [yes])],
-      [AS_VAR_SET([osmo_cv_cc_has_builtin], [no])])
+      [AS_VAR_SET([osmo_cv_cc_has_$1], [yes])],
+      [AS_VAR_SET([osmo_cv_cc_has_$1], [no])])
     ]
   )
 
-  AS_IF([test yes = AS_VAR_GET([osmo_cv_cc_has_builtin])], [
+  AS_IF([test yes = AS_VAR_GET([osmo_cv_cc_has_$1])], [
     AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_$1), 1,
       [Define to 1 if compiler has the '$1' built-in function])
   ], [
-    AC_MSG_WARN($2)
+    AC_MSG_WARN($3)
   ])
 ])
 
 dnl Check if the compiler supports runtime SIMD detection
-CHECK_BUILTIN_SUPPORT([__builtin_cpu_supports],
+CHECK_BUILTIN_SUPPORT([__builtin_cpu_supports], [__builtin_cpu_supports("sse");],
   [Runtime SIMD detection will be disabled])
 
+dnl Check for __sync_fetch_and_add().
+CHECK_BUILTIN_SUPPORT([__sync_fetch_and_and], [int x;__sync_fetch_and_and(&x,1);],
+  [Atomic operation not available, will use mutex])
+dnl Check for __sync_or_and_fetch().
+CHECK_BUILTIN_SUPPORT([__sync_or_and_fetch], [int x;__sync_or_and_fetch(&x,1);],
+  [Atomic operation not available, will use mutex])
+AS_IF([test "x$osmo_cv_cc_has___sync_fetch_and_and" = "xyes" && test "x$osmo_cv_cc_has___sync_or_and_fetch" = "xyes"], [
+    AC_DEFINE(HAVE_ATOMIC_OPS, 1, [Support all required atomic operations], [AC_MSG_WARN("At least one aotmic operation missing, will use mutex")])
+])
+
 AM_CONDITIONAL(DEVICE_UHD, [test "x$with_uhd" != "xno"])
 AM_CONDITIONAL(DEVICE_USRP1, [test "x$with_usrp1" = "xyes"])
 AM_CONDITIONAL(DEVICE_LMS, [test "x$with_lms" = "xyes"])