From cbf104e2e8ccf9b5e94fb670cf1db18d8c637f79 Mon Sep 17 00:00:00 2001 From: Darren Bane Date: Sat, 24 Dec 2022 12:15:38 +0000 Subject: [PATCH 1/3] Minimal use of C11 atomics to get the build to complete --- runtime/mercury_atomic_ops.c | 2 +- runtime/mercury_atomic_ops.h | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/runtime/mercury_atomic_ops.c b/runtime/mercury_atomic_ops.c index 334ecf8fb5..224840447e 100644 --- a/runtime/mercury_atomic_ops.c +++ b/runtime/mercury_atomic_ops.c @@ -73,7 +73,7 @@ MR_OUTLINE_DEFN( MR_OUTLINE_DEFN( void - MR_atomic_sub_int(volatile MR_Integer *addr, MR_Integer x) + MR_atomic_sub_int(volatile atomic_long *addr, MR_Integer x) , { MR_ATOMIC_SUB_INT_BODY; diff --git a/runtime/mercury_atomic_ops.h b/runtime/mercury_atomic_ops.h index 1ce95f3d82..f855e1ed61 100644 --- a/runtime/mercury_atomic_ops.h +++ b/runtime/mercury_atomic_ops.h @@ -13,6 +13,9 @@ #ifndef MERCURY_ATOMIC_OPS_H #define MERCURY_ATOMIC_OPS_H +#if (defined(MR_CLANG) || defined(MR_GNUC)) && defined(__aarch64__) +#include +#endif #include "mercury_std.h" //////////////////////////////////////////////////////////////////////////// @@ -104,7 +107,7 @@ MR_EXTERN_INLINE void MR_atomic_add_uint(volatile MR_Unsigned *addr, // Atomically subtract the second argument from the memory pointed to by the // first argument. -MR_EXTERN_INLINE void MR_atomic_sub_int(volatile MR_Integer *addr, +MR_EXTERN_INLINE void MR_atomic_sub_int(volatile atomic_long *addr, MR_Integer x); // Increment the word pointed at by the address. @@ -341,11 +344,18 @@ MR_EXTERN_INLINE MR_bool MR_atomic_dec_and_is_zero_uint( __sync_sub_and_fetch(addr, x); \ } while (0) +#elif (defined(MR_CLANG) || defined(MR_GNUC)) && defined(__aarch64__) + + #define MR_ATOMIC_SUB_INT_BODY \ + do { \ + atomic_fetch_sub(addr, x); \ + } while (0) + #endif #ifdef MR_ATOMIC_SUB_INT_BODY MR_EXTERN_INLINE void - MR_atomic_sub_int(volatile MR_Integer *addr, MR_Integer x) + MR_atomic_sub_int(volatile atomic_long *addr, MR_Integer x) { MR_ATOMIC_SUB_INT_BODY; } From 5ed824a503e5c0facac66f2634717f9110ab2746 Mon Sep 17 00:00:00 2001 From: Darren Bane Date: Sun, 12 Feb 2023 16:42:29 +0000 Subject: [PATCH 2/3] Make more use of stdatomic.h --- runtime/mercury_atomic_ops.c | 2 +- runtime/mercury_atomic_ops.h | 45 +++++++++++++++++++++++++----------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/runtime/mercury_atomic_ops.c b/runtime/mercury_atomic_ops.c index 224840447e..74be2f9dda 100644 --- a/runtime/mercury_atomic_ops.c +++ b/runtime/mercury_atomic_ops.c @@ -73,7 +73,7 @@ MR_OUTLINE_DEFN( MR_OUTLINE_DEFN( void - MR_atomic_sub_int(volatile atomic_long *addr, MR_Integer x) + MR_atomic_sub_int(volatile _Atomic MR_Integer *addr, MR_Integer x) , { MR_ATOMIC_SUB_INT_BODY; diff --git a/runtime/mercury_atomic_ops.h b/runtime/mercury_atomic_ops.h index f855e1ed61..a4d5090007 100644 --- a/runtime/mercury_atomic_ops.h +++ b/runtime/mercury_atomic_ops.h @@ -13,8 +13,10 @@ #ifndef MERCURY_ATOMIC_OPS_H #define MERCURY_ATOMIC_OPS_H -#if (defined(MR_CLANG) || defined(MR_GNUC)) && defined(__aarch64__) +#if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__) #include +#else +#define _Atomic #endif #include "mercury_std.h" @@ -107,7 +109,7 @@ MR_EXTERN_INLINE void MR_atomic_add_uint(volatile MR_Unsigned *addr, // Atomically subtract the second argument from the memory pointed to by the // first argument. -MR_EXTERN_INLINE void MR_atomic_sub_int(volatile atomic_long *addr, +MR_EXTERN_INLINE void MR_atomic_sub_int(volatile _Atomic MR_Integer *addr, MR_Integer x); // Increment the word pointed at by the address. @@ -133,7 +135,14 @@ MR_EXTERN_INLINE MR_bool MR_atomic_dec_and_is_zero_uint( //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// -#if (defined(MR_CLANG) || (MR_GNUC > 4 || (MR_GNUC == 4 && __GNUC_MINOR__ >= 1))) && \ +#if __STD_VERSION__ >= 201112L && !defined(__STD_NO_ATOMICS__) + + #define MR_COMPARE_AND_SWAP_WORD_BODY \ + do { \ + return atomic_compare_exchange_strong(addr, old, new_val); \ + } while (0) + +#elif (defined(MR_CLANG) || (MR_GNUC > 4 || (MR_GNUC == 4 && __GNUC_MINOR__ >= 1))) && \ !defined(MR_AVOID_COMPILER_INTRINSICS) // gcc 4.1 and above have builtin atomic operations. @@ -192,7 +201,17 @@ MR_EXTERN_INLINE MR_bool MR_atomic_dec_and_is_zero_uint( //////////////////////////////////////////////////////////////////////////// -#if (MR_GNUC > 4 || (MR_GNUC == 4 && __GNUC_MINOR__ >= 1)) && \ +#if __STD_VERSION__ >= 201112L && !defined(__STD_NO_ATOMICS__) + + #define MR_ATOMIC_ADD_AND_FETCH_WORD_BODY \ + do { \ + return atomic_fetch_add(addr, addend); \ + } while (0) + + #define MR_ATOMIC_ADD_AND_FETCH_INT_BODY MR_ATOMIC_ADD_AND_FETCH_WORD_BODY + #define MR_ATOMIC_ADD_AND_FETCH_UINT_BODY MR_ATOMIC_ADD_AND_FETCH_WORD_BODY + +#elif (MR_GNUC > 4 || (MR_GNUC == 4 && __GNUC_MINOR__ >= 1)) && \ !defined(MR_AVOID_COMPILER_INTRINSICS) #define MR_ATOMIC_ADD_AND_FETCH_WORD_BODY \ @@ -314,7 +333,14 @@ MR_EXTERN_INLINE MR_bool MR_atomic_dec_and_is_zero_uint( //////////////////////////////////////////////////////////////////////////// -#if (defined(MR_CLANG) || defined(MR_GNUC)) && defined(__x86_64__) && \ +#if __STDC_VERSION__ >= 201112l && !defined(__STDC_NO_ATOMICS__) + + #define MR_ATOMIC_SUB_INT_BODY \ + do { \ + atomic_fetch_sub(addr, x); \ + } while (0) + +#elif (defined(MR_CLANG) || defined(MR_GNUC)) && defined(__x86_64__) && \ !defined(MR_AVOID_HANDWRITTEN_ASSEMBLER) #define MR_ATOMIC_SUB_INT_BODY \ @@ -344,18 +370,11 @@ MR_EXTERN_INLINE MR_bool MR_atomic_dec_and_is_zero_uint( __sync_sub_and_fetch(addr, x); \ } while (0) -#elif (defined(MR_CLANG) || defined(MR_GNUC)) && defined(__aarch64__) - - #define MR_ATOMIC_SUB_INT_BODY \ - do { \ - atomic_fetch_sub(addr, x); \ - } while (0) - #endif #ifdef MR_ATOMIC_SUB_INT_BODY MR_EXTERN_INLINE void - MR_atomic_sub_int(volatile atomic_long *addr, MR_Integer x) + MR_atomic_sub_int(volatile _Atomic MR_Integer *addr, MR_Integer x) { MR_ATOMIC_SUB_INT_BODY; } From 11361deb09dd8f81e6f1acbfaec272e5b5fe5419 Mon Sep 17 00:00:00 2001 From: Darren Bane Date: Mon, 13 Feb 2023 00:25:23 +0000 Subject: [PATCH 3/3] Finish switching to stdatomic.h operations --- runtime/mercury_atomic_ops.c | 4 ++-- runtime/mercury_atomic_ops.h | 35 +++++++++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/runtime/mercury_atomic_ops.c b/runtime/mercury_atomic_ops.c index 74be2f9dda..06359efa60 100644 --- a/runtime/mercury_atomic_ops.c +++ b/runtime/mercury_atomic_ops.c @@ -109,7 +109,7 @@ MR_OUTLINE_DEFN( MR_OUTLINE_DEFN( MR_bool - MR_atomic_dec_and_is_zero_int(volatile MR_Integer *addr) + MR_atomic_dec_and_is_zero_int(volatile _Atomic MR_Integer *addr) , { MR_ATOMIC_DEC_AND_IS_ZERO_INT_BODY; @@ -118,7 +118,7 @@ MR_OUTLINE_DEFN( MR_OUTLINE_DEFN( MR_bool - MR_atomic_dec_and_is_zero_uint(volatile MR_Unsigned *addr) + MR_atomic_dec_and_is_zero_uint(volatile _Atomic MR_Unsigned *addr) , { MR_ATOMIC_DEC_AND_IS_ZERO_UINT_BODY; diff --git a/runtime/mercury_atomic_ops.h b/runtime/mercury_atomic_ops.h index a4d5090007..617689f6fd 100644 --- a/runtime/mercury_atomic_ops.h +++ b/runtime/mercury_atomic_ops.h @@ -125,9 +125,9 @@ MR_EXTERN_INLINE void MR_atomic_dec_int(volatile MR_Integer *addr); // zero after the decrement. MR_EXTERN_INLINE MR_bool MR_atomic_dec_and_is_zero_int( - volatile MR_Integer *addr); + volatile _Atomic MR_Integer *addr); MR_EXTERN_INLINE MR_bool MR_atomic_dec_and_is_zero_uint( - volatile MR_Unsigned *addr); + volatile _Atomic MR_Unsigned *addr); // For information about GCC's builtins for atomic operations see: // http://gcc.gnu.org/onlinedocs/gcc-4.2.4/gcc/Atomic-Builtins.html @@ -490,7 +490,19 @@ MR_EXTERN_INLINE MR_bool MR_atomic_dec_and_is_zero_uint( // Note that on x86(_64) we have to use the sub instruction rather than the // dec instruction because we need it to set the CPU flags. -#if (defined(MR_CLANG) || defined(MR_GNUC)) && defined(__x86_64__) && \ +#if __STDC_VERSION__ >= 201112l && !defined(__STDC_NO_ATOMICS__) + + #define MR_ATOMIC_DEC_AND_IS_ZERO_WORD_BODY \ + do { \ + return (atomic_fetch_sub(addr, 1) == 1); \ + } while (0) + + #define MR_ATOMIC_DEC_AND_IS_ZERO_INT_BODY \ + MR_ATOMIC_DEC_AND_IS_ZERO_WORD_BODY + #define MR_ATOMIC_DEC_AND_IS_ZERO_UINT_BODY \ + MR_ATOMIC_DEC_AND_IS_ZERO_WORD_BODY + +#elif (defined(MR_CLANG) || defined(MR_GNUC)) && defined(__x86_64__) && \ !defined(MR_AVOID_HANDWRITTEN_ASSEMBLER) // This could be trivially implemented using the __sync_sub_and_fetch compiler @@ -548,7 +560,7 @@ MR_EXTERN_INLINE MR_bool MR_atomic_dec_and_is_zero_uint( #ifdef MR_ATOMIC_DEC_AND_IS_ZERO_INT_BODY MR_EXTERN_INLINE MR_bool - MR_atomic_dec_and_is_zero_int(volatile MR_Integer *addr) + MR_atomic_dec_and_is_zero_int(volatile _Atomic MR_Integer *addr) { MR_ATOMIC_DEC_AND_IS_ZERO_INT_BODY; } @@ -556,7 +568,7 @@ MR_EXTERN_INLINE MR_bool MR_atomic_dec_and_is_zero_uint( #ifdef MR_ATOMIC_DEC_AND_IS_ZERO_UINT_BODY MR_EXTERN_INLINE MR_bool - MR_atomic_dec_and_is_zero_uint(volatile MR_Unsigned *addr) + MR_atomic_dec_and_is_zero_uint(volatile _Atomic MR_Unsigned *addr) { MR_ATOMIC_DEC_AND_IS_ZERO_UINT_BODY; } @@ -571,7 +583,18 @@ MR_EXTERN_INLINE MR_bool MR_atomic_dec_and_is_zero_uint( // Memory fence operations. -#if ( defined(MR_CLANG) || defined(MR_GNUC) ) && \ +#if __STDC_VERSION__ >= 201112l && !defined(__STDC_NO_ATOMICS__) + + // Similar to the gcc __sync_* code below, this could be optimized + + #define MR_CPU_MFENCE \ + do { \ + atomic_thread_fence(memory_order_seq_cst); \ + } while (0) + #define MR_CPU_SFENCE MR_CPU_MFENCE + #define MR_CPU_LFENCE MR_CPU_MFENCE + +#elif ( defined(MR_CLANG) || defined(MR_GNUC) ) && \ ( defined(__i386__) || defined(__x86_64__) ) && \ !defined(MR_AVOID_HANDWRITTEN_ASSEMBLER)