From 439fa2eae78a8900bda120072335be19d626498c Mon Sep 17 00:00:00 2001
From: "Yann E. MORIN" <yann.morin.1998@free.fr>
Date: Sun, 28 Dec 2014 23:39:40 +0100
Subject: [PATCH] erts/ethread: instruct libatomic_ops we do require CAS

We do require compare-and-swap (CAS), so we must instruct libatomic_ops
to provide it, even if the architecture does not have instructions for
it.

For example, on ARM, LDREX is required for fast CAS. But LDREX is only
available on ARMv6, so by default libatomic_ops will not have CAS for
anything below, like ARMv5. But ARMv5 is always UP, so using an
emulated CAS (that is signal-asyn-safe) is still possible (albeit much
slower).

Tell libatomic_ops to provide CAS, even if the hardware is not capable
of it, by using emulated CAS, as per libatomic_ops dosc:
    https://github.com/ivmai/libatomic_ops/blob/master/doc/README.txt#L28

    If this is included after defining AO_REQUIRE_CAS, then the package
    will make an attempt to emulate compare-and-swap in a way that (at
    least on Linux) should still be async-signal-safe.

Thanks go to Thomas for all this insight! :-)
Thanks go to Frank for reporting the issue! :-)

Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: Frank Hunleth <fhunleth@troodon-software.com>
---
 erts/include/internal/libatomic_ops/ethread.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/erts/include/internal/libatomic_ops/ethread.h b/erts/include/internal/libatomic_ops/ethread.h
index d65ee19..71d3598 100644
--- a/erts/include/internal/libatomic_ops/ethread.h
+++ b/erts/include/internal/libatomic_ops/ethread.h
@@ -35,6 +35,7 @@
 
 #define ETHR_NATIVE_IMPL__ "libatomic_ops"
 
+#define AO_REQUIRE_CAS
 #include "atomic_ops.h"
 #include "ethr_membar.h"
 #include "ethr_atomic.h"
diff --git a/erts/aclocal.m4 b/erts/aclocal.m4
index d65ee19..71d3598 100644
--- a/erts/aclocal.m4
+++ b/erts/aclocal.m4
@@ -1414,7 +1414,8 @@
 	    	    fi;;
 	    esac
 	    ethr_have_libatomic_ops=no
-	    AC_TRY_LINK([#include "atomic_ops.h"],
+	    AC_TRY_LINK([#define AO_REQUIRE_CAS
+                    #include "atomic_ops.h"],
 	    	        [
 	    	    	    volatile AO_t x;
 	    	    	    AO_t y;
@@ -1455,6 +1455,7 @@
 	        AC_CHECK_SIZEOF(AO_t, ,
 	    	    	        [
 	    	    	    	    #include <stdio.h>
+	    	    	    	    #define AO_REQUIRE_CAS
 	    	    	    	    #include "atomic_ops.h"
 	    	    	        ])
 	        AC_DEFINE_UNQUOTED(ETHR_SIZEOF_AO_T, $ac_cv_sizeof_AO_t, [Define to the size of AO_t if libatomic_ops is used])
-- 
1.9.1

