From c67e1f018d4bf055b5c1113134a4719472eea056 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Thu, 19 Jan 2023 15:24:58 +0100 Subject: [PATCH] Use __c11 atomic macros when they are available (and fix the LLVM support) Co-authored-by: Pierre Alain --- nolibc/include/stdatomic.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/nolibc/include/stdatomic.h b/nolibc/include/stdatomic.h index af6da749..020383ff 100644 --- a/nolibc/include/stdatomic.h +++ b/nolibc/include/stdatomic.h @@ -1,6 +1,11 @@ #ifndef _STDATOMIC_H #define _STDATOMIC_H +// Compatibility with non-clang compilers +#ifndef __has_builtin +# define __has_builtin(x) 0 +#endif + #define atomic_load_explicit(x, mode) ( *x ) #define atomic_load(x) ( *x ) @@ -9,13 +14,22 @@ extern int memory_order_acquire; extern int memory_order_relaxed; extern int memory_order_seq_cst; +#if __has_builtin(__c11_atomic_fetch_add) +#define atomic_fetch_add(X, Y) __c11_atomic_fetch_add(X, Y, __ATOMIC_SEQ_CST) +#else #define atomic_fetch_add(X, Y) ({ __auto_type tmp = *X; *X = tmp + Y; tmp; }) +#endif + #define atomic_fetch_add_explicit(X, Y, MOD) atomic_fetch_add(X, Y) #define atomic_thread_fence(MO) do {} while (0) typedef unsigned long long atomic_uint_fast64_t; +#if __has_builtin(__c11_atomic_compare_exchange_strong) +#define atomic_compare_exchange_strong(OBJ, EXPECTED, DESIRED) \ + __c11_atomic_compare_exchange_strong(OBJ, EXPECTED, DESIRED) +#else #define atomic_compare_exchange_strong(OBJ, EXPECTED, DESIRED) \ ({ int ret = 0; \ if (*OBJ == *EXPECTED) { \ @@ -24,20 +38,31 @@ typedef unsigned long long atomic_uint_fast64_t; } \ ret; \ }) +#endif +#if __has_builtin(__c11_atomic_exchange) +#define atomic_exchange(OBJ, DESIRED) \ + __c11_atomic_exchange(OBJ, DESIRED) +#else #define atomic_exchange(OBJ, DESIRED) \ ({ __auto_type tmp = *OBJ; \ *OBJ = DESIRED; \ tmp; \ }) +#endif #define atomic_store(OBJ, DESIRED) do { *OBJ = DESIRED; } while(0) #define atomic_store_explicit(OBJ, DESIRED, ORDER) atomic_store(OBJ, DESIRED) +#if __has_builtin(__c11_atomic_fetch_or) +#define atomic_fetch_or(OBJ, ARG) \ + __c11_atomic_fetch_or(OBJ, ARG) +#else #define atomic_fetch_or(OBJ, ARG) \ ({ __auto_type tmp = *OBJ; \ *OBJ = *OBJ | ARG; \ tmp; \ }) +#endif #endif