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.

ok jsg@
This commit is contained in:
kettenis 2020-04-03 07:26:18 +00:00
parent d1d3f7dcb4
commit cd2d30e6df

View File

@ -158,6 +158,17 @@ __sync_val_compare_and_swap_4(uint32_t *ptr, uint32_t oldval, uint32_t newval)
}
#endif /* MISSING_32BIT_ATOMICS */
#ifdef __clang__
#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
#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
#endif
WEAK uint64_t
__sync_add_and_fetch_8(uint64_t *ptr, uint64_t val)
{
@ -184,6 +195,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;
}
#ifdef USE_GCC_ATOMIC_BUILTINS
WEAK uint64_t
__sync_val_compare_and_swap_8(uint64_t *ptr, uint64_t oldval, uint64_t newval)