From f12c107b030b0aacc0c8b11c99fdce13f38bc98f Mon Sep 17 00:00:00 2001 From: Jonathan Gray Date: Mon, 15 Jun 2020 14:40:06 +1000 Subject: [PATCH] util/u_atomic: fix build on clang archs without 64-bit atomics Make this build on clang architectures that don't have 64-bit atomic instructions. Clang doesn't allow redeclaration (and therefore redefinition) of the __sync_* builtins. Use #pragma redefine_extname to work around that restriction. Clang also turns __sync_add_and_fetch into __sync_fetch_and_add (and __sync_sub_and_fetch into __sync_fetch_and_sub) in certain cases, so provide these functions as well. Fixes: a6a38a038bd ("util/u_atomic: provide 64bit atomics where they're missing") patch from Mark Kettenis Signed-off-by: Jonathan Gray Reviewed-by: Ilia Mirkin Part-of: --- src/util/u_atomic.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/util/u_atomic.c b/src/util/u_atomic.c index e4bffa8534e..5a5eab411c4 100644 --- a/src/util/u_atomic.c +++ b/src/util/u_atomic.c @@ -34,6 +34,21 @@ static pthread_mutex_t sync_mutex = PTHREAD_MUTEX_INITIALIZER; +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wmissing-prototypes" +#pragma redefine_extname __sync_add_and_fetch_8_c __sync_add_and_fetch_8 +#pragma redefine_extname __sync_sub_and_fetch_8_c __sync_sub_and_fetch_8 +#pragma redefine_extname __sync_fetch_and_add_8_c __sync_fetch_and_add_8 +#pragma redefine_extname __sync_fetch_and_sub_8_c __sync_fetch_and_sub_8 +#pragma redefine_extname __sync_val_compare_and_swap_8_c \ + __sync_val_compare_and_swap_8 +#define __sync_add_and_fetch_8 __sync_add_and_fetch_8_c +#define __sync_sub_and_fetch_8 __sync_sub_and_fetch_8_c +#define __sync_fetch_and_add_8 __sync_fetch_and_add_8_c +#define __sync_fetch_and_sub_8 __sync_fetch_and_sub_8_c +#define __sync_val_compare_and_swap_8 __sync_val_compare_and_swap_8_c +#endif + WEAK uint64_t __sync_add_and_fetch_8(uint64_t *ptr, uint64_t val) { @@ -60,6 +75,32 @@ __sync_sub_and_fetch_8(uint64_t *ptr, uint64_t val) return r; } +WEAK uint64_t +__sync_fetch_and_add_8(uint64_t *ptr, uint64_t val) +{ + uint64_t r; + + pthread_mutex_lock(&sync_mutex); + r = *ptr; + *ptr += val; + pthread_mutex_unlock(&sync_mutex); + + return r; +} + +WEAK uint64_t +__sync_fetch_and_sub_8(uint64_t *ptr, uint64_t val) +{ + uint64_t r; + + pthread_mutex_lock(&sync_mutex); + r = *ptr; + *ptr -= val; + pthread_mutex_unlock(&sync_mutex); + + return r; +} + WEAK uint64_t __sync_val_compare_and_swap_8(uint64_t *ptr, uint64_t oldval, uint64_t newval) {