configure.ac | 16 ++++++++++++++++ meson-cc-tests/stdatomic-primitives-test.c | 8 ++++++++ meson.build | 4 ++++ src/fcatomic.h | 21 +++++++++++++++++++++ src/fccache.c | 2 +- 5 files changed, 50 insertions(+), 1 deletion(-) New commits: commit 012ffaac754543eed1d4f4f5de786626f31d5c36 Author: Alex Richardson <Alexander.Richardson@xxxxxxxxxxxx> Date: Mon Jul 12 14:57:49 2021 +0100 Add support for C11 stdatomic atomics This fixes deprecation warnings when building for macOS >= 10.12 systems. Additionally, using stdatomic.h (or the more modern __atomic_ builtins) is required when targeting CHERI-enabled architectures such as CHERI-RISC-V or Arm's Morello since the compiler rejects __sync_* atomic for pointer types (they only work with integers). diff --git a/configure.ac b/configure.ac index 7c1a697..3bbd969 100644 --- a/configure.ac +++ b/configure.ac @@ -663,6 +663,22 @@ dnl =========================================================================== # Thread-safety primitives # +AC_CACHE_CHECK([stdatomic.h atomic primitives], fc_cv_have_stdatomic_atomic_primitives, [ + fc_cv_have_stdatomic_atomic_primitives=false + AC_TRY_LINK([ + #include <stdatomic.h> + + void memory_barrier (void) { atomic_thread_fence (memory_order_acq_rel); } + int atomic_add (atomic_int *i) { return atomic_fetch_add_explicit (i, 1, memory_order_relaxed); } + int mutex_trylock (atomic_flag *m) { return atomic_flag_test_and_set_explicit (m, memory_order_acquire); } + void mutex_unlock (atomic_flag *m) { atomic_flag_clear_explicit (m, memory_order_release); } + ], [], fc_cv_have_stdatomic_atomic_primitives=true + ) +]) +if $fc_cv_have_stdatomic_atomic_primitives; then + AC_DEFINE(HAVE_STDATOMIC_PRIMITIVES, 1, [Have Intel __sync_* atomic primitives]) +fi + AC_CACHE_CHECK([for Intel atomic primitives], fc_cv_have_intel_atomic_primitives, [ fc_cv_have_intel_atomic_primitives=false AC_TRY_LINK([ diff --git a/meson-cc-tests/stdatomic-primitives-test.c b/meson-cc-tests/stdatomic-primitives-test.c new file mode 100644 index 0000000..6d11d34 --- /dev/null +++ b/meson-cc-tests/stdatomic-primitives-test.c @@ -0,0 +1,8 @@ +#include <stdatomic.h> + +void memory_barrier (void) { atomic_thread_fence (memory_order_acq_rel); } +int atomic_add (atomic_int *i) { return atomic_fetch_add_explicit (i, 1, memory_order_relaxed); } +int mutex_trylock (atomic_flag *m) { return atomic_flag_test_and_set_explicit (m, memory_order_acquire); } +void mutex_unlock (atomic_flag *m) { atomic_flag_clear_explicit (m, memory_order_release); } + +int main(void) { return 0;} diff --git a/meson.build b/meson.build index 0ec3dc6..64cae44 100644 --- a/meson.build +++ b/meson.build @@ -190,6 +190,10 @@ else conf.set('FLEXIBLE_ARRAY_MEMBER', 1) endif +if cc.links(files('meson-cc-tests/stdatomic-primitives-test.c'), name: 'stdatomic.h atomics') + conf.set('HAVE_STDATOMIC_PRIMITIVES', 1) +endif + if cc.links(files('meson-cc-tests/intel-atomic-primitives-test.c'), name: 'Intel atomics') conf.set('HAVE_INTEL_ATOMIC_PRIMITIVES', 1) endif diff --git a/src/fcatomic.h b/src/fcatomic.h index 9f56b3d..a41b0aa 100644 --- a/src/fcatomic.h +++ b/src/fcatomic.h @@ -51,6 +51,25 @@ typedef <type> fc_atomic_int_t; #define fc_atomic_ptr_cmpexch(P,O,N) *(P) == (O) ? (*(P) = (N), FcTrue) : FcFalse // atomic release +#elif !defined(FC_NO_MT) && defined(HAVE_STDATOMIC_PRIMITIVES) + +#include <stdatomic.h> + +typedef atomic_int fc_atomic_int_t; +#define FC_ATOMIC_INT_FORMAT "d" +#define fc_atomic_int_add(AI, V) atomic_fetch_add (&(AI), (V)) + +#define fc_atomic_ptr_get(P) atomic_load ((_Atomic(void *)*) (P)) +static inline FcBool _fc_atomic_ptr_cmpexch(_Atomic(void *)*P, void * O, _Atomic(void *) N) { + return atomic_compare_exchange_strong(P, &O, N); +} +#define fc_atomic_ptr_cmpexch(P,O,N) _fc_atomic_ptr_cmpexch ((_Atomic(void *)*) (P), (O), (N)) + +/* Casting -1 to _Atomic(int) produces a compiler error with Clang (but not GCC) + * so we have to override FC_REF_CONSTANT_VALUE for stdatomic.h atomics. + * See https://bugs.llvm.org/show_bug.cgi?id=40249. */ +#define FC_REF_CONSTANT_VALUE (-1) + #elif !defined(FC_NO_MT) && defined(_MSC_VER) || defined(__MINGW32__) #include "fcwindows.h" @@ -137,7 +156,9 @@ typedef int fc_atomic_int_t; #endif /* reference count */ +#ifndef FC_REF_CONSTANT_VALUE #define FC_REF_CONSTANT_VALUE ((fc_atomic_int_t) -1) +#endif #define FC_REF_CONSTANT {FC_REF_CONSTANT_VALUE} typedef struct _FcRef { fc_atomic_int_t count; } FcRef; static inline void FcRefInit (FcRef *r, int v) { r->count = v; } diff --git a/src/fccache.c b/src/fccache.c index b2392d3..ae3b9e3 100644 --- a/src/fccache.c +++ b/src/fccache.c @@ -135,7 +135,7 @@ FcCacheIsMmapSafe (int fd) status = use ? MMAP_USE : MMAP_DONT_USE; else status = MMAP_CHECK_FS; - (void) fc_atomic_ptr_cmpexch (&static_status, NULL, (void *) status); + (void) fc_atomic_ptr_cmpexch (&static_status, NULL, (void *) (intptr_t) status); } if (status == MMAP_CHECK_FS) _______________________________________________ Fontconfig mailing list Fontconfig@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/fontconfig