File 1132-Improve-memory-barrier-usage-for-ARMv8.patch of Package erlang

From 77f5bc8acf1609dcded285e582f38fb343ec9268 Mon Sep 17 00:00:00 2001
From: Rickard Green <rickard@erlang.org>
Date: Wed, 10 Feb 2021 19:42:33 +0100
Subject: [PATCH 2/3] Improve memory barrier usage for ARMv8

We will now use the more lightweight memory barrier 'dmb ld' (available
in ARMv8) instead of a full 'dmb sy' memory barrier as LoadLoad and/or
LoadStore barriers.
---
 erts/aclocal.m4                               | 41 +++++++++++++++----
 .../internal/ethread_header_config.h.in       | 14 ++++++-
 erts/include/internal/gcc/ethr_membar.h       | 41 ++++++++++++++++++-
 3 files changed, 85 insertions(+), 11 deletions(-)

diff --git a/erts/aclocal.m4 b/erts/aclocal.m4
index d237f7ae08..b5816ecc65 100644
--- a/erts/aclocal.m4
+++ b/erts/aclocal.m4
@@ -1374,28 +1374,55 @@ AC_DEFUN(ETHR_CHK_GCC_ATOMIC_OPS,
     ETHR_CHK_GCC_ATOMIC_OP__(__atomic_compare_exchange_n)
 
     ethr_have_gcc_native_atomics=no
-    ethr_arm_dbm_instr_val=0
+    ethr_arm_dbm_sy_instr_val=0
+    ethr_arm_dbm_st_instr_val=0
+    ethr_arm_dbm_ld_instr_val=0
     case "$GCC-$host_cpu" in
 	yes-arm*)
-	    AC_CACHE_CHECK([for ARM DMB instruction], ethr_cv_arm_dbm_instr,
+	    AC_CACHE_CHECK([for ARM 'dmb sy' instruction], ethr_cv_arm_dbm_sy_instr,
 			   [
-				ethr_cv_arm_dbm_instr=no
+				ethr_cv_arm_dbm_sy_instr=no
 				AC_TRY_LINK([],
 					    [
 						__asm__ __volatile__("dmb sy" : : : "memory");
-						__asm__ __volatile__("dmb st" : : : "memory");
 					    ],
-					    [ethr_cv_arm_dbm_instr=yes])
+					    [ethr_cv_arm_dbm_sy_instr=yes])
 			   ])
-	    if test $ethr_cv_arm_dbm_instr = yes; then
+	    if test $ethr_cv_arm_dbm_sy_instr = yes; then
 		ethr_arm_dbm_instr_val=1
 		test $ethr_cv_64bit___atomic_compare_exchange_n = yes &&
 		    ethr_have_gcc_native_atomics=yes
+	    fi
+	    AC_CACHE_CHECK([for ARM 'dmb st' instruction], ethr_cv_arm_dbm_st_instr,
+			   [
+				ethr_cv_arm_dbm_st_instr=no
+				AC_TRY_LINK([],
+					    [
+						__asm__ __volatile__("dmb st" : : : "memory");
+					    ],
+					    [ethr_cv_arm_dbm_st_instr=yes])
+			   ])
+	    if test $ethr_cv_arm_dbm_sy_instr = yes; then
+		ethr_arm_dbm_st_instr_val=1
+	    fi
+	    AC_CACHE_CHECK([for ARM 'dmb ld' instruction], ethr_cv_arm_dbm_ld_instr,
+			   [
+				ethr_cv_arm_dbm_ld_instr=no
+				AC_TRY_LINK([],
+					    [
+						__asm__ __volatile__("dmb ld" : : : "memory");
+					    ],
+					    [ethr_cv_arm_dbm_ld_instr=yes])
+			   ])
+	    if test $ethr_cv_arm_dbm_ld_instr = yes; then
+		ethr_arm_dbm_ld_instr_val=1
 	    fi;;
 	*)
 	    ;;
     esac
-    AC_DEFINE_UNQUOTED([ETHR_HAVE_GCC_ASM_ARM_DMB_INSTRUCTION], [$ethr_arm_dbm_instr_val], [Define as a boolean indicating whether you have a gcc compatible compiler capable of generating the ARM DMB instruction, and are compiling for an ARM processor with ARM DMB instruction support, or not])
+    AC_DEFINE_UNQUOTED([ETHR_HAVE_GCC_ASM_ARM_DMB_INSTRUCTION], [$ethr_arm_dbm_instr_val], [Define as a boolean indicating whether you have a gcc compatible compiler capable of generating the ARM 'dmb sy' instruction, and are compiling for an ARM processor with ARM DMB instruction support, or not])
+    AC_DEFINE_UNQUOTED([ETHR_HAVE_GCC_ASM_ARM_DMB_ST_INSTRUCTION], [$ethr_arm_dbm_st_instr_val], [Define as a boolean indicating whether you have a gcc compatible compiler capable of generating the ARM 'dmb st' instruction, and are compiling for an ARM processor with ARM DMB instruction support, or not])
+    AC_DEFINE_UNQUOTED([ETHR_HAVE_GCC_ASM_ARM_DMB_LD_INSTRUCTION], [$ethr_arm_dbm_ld_instr_val], [Define as a boolean indicating whether you have a gcc compatible compiler capable of generating the ARM 'dmb ld' instruction, and are compiling for an ARM processor with ARM DMB instruction support, or not])
     test $ethr_cv_32bit___sync_val_compare_and_swap = yes &&
     	ethr_have_gcc_native_atomics=yes
     test $ethr_cv_64bit___sync_val_compare_and_swap = yes &&
diff --git a/erts/include/internal/ethread_header_config.h.in b/erts/include/internal/ethread_header_config.h.in
index 6309f10439..80ec4dd864 100644
--- a/erts/include/internal/ethread_header_config.h.in
+++ b/erts/include/internal/ethread_header_config.h.in
@@ -86,10 +86,20 @@
 #undef ETHR_SPARC_RMO
 
 /* Define as a boolean indicating whether you have a gcc compatible compiler
-   capable of generating the ARM DMB instruction, and are compiling for an ARM
-   processor with ARM DMB instruction support, or not */
+   capable of generating the ARM 'dmb sy' instruction, and are compiling for
+   an ARM processor with ARM DMB instruction support, or not */
 #undef ETHR_HAVE_GCC_ASM_ARM_DMB_INSTRUCTION
 
+/* Define as a boolean indicating whether you have a gcc compatible compiler
+   capable of generating the ARM 'dmb ld' instruction, and are compiling for
+   an ARM processor with ARM DMB instruction support, or not */
+#undef ETHR_HAVE_GCC_ASM_ARM_DMB_LD_INSTRUCTION
+
+/* Define as a boolean indicating whether you have a gcc compatible compiler
+   capable of generating the ARM 'dmb st' instruction, and are compiling for
+   an ARM processor with ARM DMB instruction support, or not */
+#undef ETHR_HAVE_GCC_ASM_ARM_DMB_ST_INSTRUCTION
+
 /* Define as a bitmask corresponding to the word sizes that
    __sync_synchronize() can handle on your system */
 #undef ETHR_HAVE___sync_synchronize
diff --git a/erts/include/internal/gcc/ethr_membar.h b/erts/include/internal/gcc/ethr_membar.h
index d697ee4155..4e1eb1117e 100644
--- a/erts/include/internal/gcc/ethr_membar.h
+++ b/erts/include/internal/gcc/ethr_membar.h
@@ -149,14 +149,51 @@ ethr_full_fence__(void)
     __asm__ __volatile__("dmb sy" : : : "memory");
 }
 
+#if ETHR_HAVE_GCC_ASM_ARM_DMB_ST_INSTRUCTION
 static __inline__ __attribute__((__always_inline__)) void
 ethr_store_fence__(void)
 {
+    /* StoreStore */
     __asm__ __volatile__("dmb st" : : : "memory");
 }
+#endif
 
-#define ETHR_MEMBAR(B) \
- ETHR_CHOOSE_EXPR((B) == ETHR_StoreStore, ethr_store_fence__(), ethr_full_fence__())
+#if ETHR_HAVE_GCC_ASM_ARM_DMB_LD_INSTRUCTION
+static __inline__ __attribute__((__always_inline__)) void
+ethr_load_fence__(void)
+{
+    /* LoadLoad and LoadStore */
+    __asm__ __volatile__("dmb ld" : : : "memory");
+}
+#endif
+
+#if ETHR_HAVE_GCC_ASM_ARM_DMB_ST_INSTRUCTION && ETHR_HAVE_GCC_ASM_ARM_DMB_LD_INSTRUCTION
+/* sy, st & ld */
+#define ETHR_MEMBAR(B)                                                  \
+    ETHR_CHOOSE_EXPR((B) == ETHR_StoreStore,                            \
+                     ethr_store_fence__(),                              \
+                     ETHR_CHOOSE_EXPR((B) & (ETHR_StoreStore            \
+                                             | ETHR_StoreLoad),         \
+                                      ethr_full_fence__(),              \
+                                      ethr_load_fence__()))
+#elif ETHR_HAVE_GCC_ASM_ARM_DMB_ST_INSTRUCTION
+/* sy & st */
+#define ETHR_MEMBAR(B)                                                  \
+    ETHR_CHOOSE_EXPR((B) == ETHR_StoreStore,                            \
+                     ethr_store_fence__(), \
+                     ethr_full_fence__())
+#elif ETHR_HAVE_GCC_ASM_ARM_DMB_LD_INSTRUCTION
+/* sy & ld */
+#define ETHR_MEMBAR(B)                                                  \
+    ETHR_CHOOSE_EXPR((B) & (ETHR_StoreStore                             \
+                            | ETHR_StoreLoad),                          \
+                     ethr_full_fence__(),                               \
+                     ethr_load_fence__())
+#else
+/* sy */
+#define ETHR_MEMBAR(B)                                                  \
+ ethr_full_fence__()
+#endif
 
 #elif ETHR_HAVE___sync_synchronize
 
-- 
2.26.2

openSUSE Build Service is sponsored by