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: a6a38a038b ("util/u_atomic: provide 64bit atomics where they're missing")
patch from Mark Kettenis

Signed-off-by: Jonathan Gray <jsg@jsg.id.au>
Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6511>
This commit is contained in:
Jonathan Gray 2020-06-15 14:40:06 +10:00 committed by Marge Bot
parent d07df90bf4
commit f12c107b03
1 changed files with 41 additions and 0 deletions

View File

@ -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)
{