From 1ea339b69725cb2f30b5a84cb7ca96111c9a637b Mon Sep 17 00:00:00 2001 From: Torvald Riegel Date: Sat, 18 Oct 2014 01:02:59 +0200 Subject: [PATCH] Add arch-specific configuration for C11 atomics support. This sets __HAVE_64B_ATOMICS if provided. It also sets USE_ATOMIC_COMPILER_BUILTINS to true if the existing atomic ops use the __atomic* builtins (aarch64, mips partially) or if this has been tested (x86_64); otherwise, this is set to false so that C11 atomics will be based on the existing atomic operations. --- ChangeLog | 45 +++++++++++++++++++ sysdeps/aarch64/bits/atomic.h | 2 + sysdeps/alpha/bits/atomic.h | 3 ++ sysdeps/arm/bits/atomic.h | 3 ++ sysdeps/i386/i486/bits/atomic.h | 3 ++ sysdeps/ia64/bits/atomic.h | 3 ++ sysdeps/m68k/coldfire/bits/atomic.h | 4 ++ sysdeps/m68k/m680x0/m68020/bits/atomic.h | 3 ++ sysdeps/microblaze/bits/atomic.h | 3 ++ sysdeps/mips/bits/atomic.h | 10 +++++ sysdeps/powerpc/powerpc32/bits/atomic.h | 3 ++ sysdeps/powerpc/powerpc64/bits/atomic.h | 3 ++ sysdeps/s390/bits/atomic.h | 4 ++ sysdeps/sparc/sparc32/bits/atomic.h | 3 ++ sysdeps/sparc/sparc32/sparcv9/bits/atomic.h | 3 ++ sysdeps/sparc/sparc64/bits/atomic.h | 3 ++ sysdeps/tile/tilegx/bits/atomic.h | 3 ++ sysdeps/tile/tilepro/bits/atomic.h | 3 ++ sysdeps/unix/sysv/linux/hppa/bits/atomic.h | 3 ++ .../sysv/linux/m68k/coldfire/bits/atomic.h | 3 ++ sysdeps/unix/sysv/linux/sh/bits/atomic.h | 3 ++ sysdeps/x86_64/bits/atomic.h | 6 +++ 22 files changed, 119 insertions(+) diff --git a/ChangeLog b/ChangeLog index 6199b7e692..cf1b122092 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,48 @@ +2014-11-20 Torvald Riegel + + * sysdeps/aarch64/bits/atomic.h (__HAVE_64B_ATOMICS, + USE_ATOMIC_COMPILER_BUILTINS): Define. + * sysdeps/alpha/bits/atomic.h (__HAVE_64B_ATOMICS, + USE_ATOMIC_COMPILER_BUILTINS): Likewise. + * sysdeps/arm/bits/atomic.h (__HAVE_64B_ATOMICS, + USE_ATOMIC_COMPILER_BUILTINS): Likewise. + * sysdeps/i386/i486/bits/atomic.h (__HAVE_64B_ATOMICS, + USE_ATOMIC_COMPILER_BUILTINS): Likewise. + * sysdeps/ia64/bits/atomic.h (__HAVE_64B_ATOMICS, + USE_ATOMIC_COMPILER_BUILTINS): Likewise. + * sysdeps/m68k/coldfire/bits/atomic.h (__HAVE_64B_ATOMICS, + USE_ATOMIC_COMPILER_BUILTINS): Likewise. + * sysdeps/m68k/m680x0/m68020/bits/atomic.h (__HAVE_64B_ATOMICS, + USE_ATOMIC_COMPILER_BUILTINS): Likewise. + * sysdeps/microblaze/bits/atomic.h (__HAVE_64B_ATOMICS, + USE_ATOMIC_COMPILER_BUILTINS): Likewise. + * sysdeps/mips/bits/atomic.h (__HAVE_64B_ATOMICS, + USE_ATOMIC_COMPILER_BUILTINS): Likewise. + * sysdeps/powerpc/powerpc32/bits/atomic.h (__HAVE_64B_ATOMICS, + USE_ATOMIC_COMPILER_BUILTINS): Likewise. + * sysdeps/powerpc/powerpc64/bits/atomic.h (__HAVE_64B_ATOMICS, + USE_ATOMIC_COMPILER_BUILTINS): Likewise. + * sysdeps/s390/bits/atomic.h (__HAVE_64B_ATOMICS, + USE_ATOMIC_COMPILER_BUILTINS): Likewise. + * sysdeps/sparc/sparc32/bits/atomic.h (__HAVE_64B_ATOMICS, + USE_ATOMIC_COMPILER_BUILTINS): Likewise. + * sysdeps/sparc/sparc32/sparcv9/bits/atomic.h (__HAVE_64B_ATOMICS, + USE_ATOMIC_COMPILER_BUILTINS): Likewise. + * sysdeps/sparc/sparc64/bits/atomic.h (__HAVE_64B_ATOMICS, + USE_ATOMIC_COMPILER_BUILTINS): Likewise. + * sysdeps/tile/tilegx/bits/atomic.h (__HAVE_64B_ATOMICS, + USE_ATOMIC_COMPILER_BUILTINS): Likewise. + * sysdeps/tile/tilepro/bits/atomic.h (__HAVE_64B_ATOMICS, + USE_ATOMIC_COMPILER_BUILTINS): Likewise. + * sysdeps/unix/sysv/linux/hppa/bits/atomic.h (__HAVE_64B_ATOMICS, + USE_ATOMIC_COMPILER_BUILTINS): Likewise. + * sysdeps/unix/sysv/linux/m68k/coldfire/bits/atomic.h + (__HAVE_64B_ATOMICS, USE_ATOMIC_COMPILER_BUILTINS): Likewise. + * sysdeps/unix/sysv/linux/sh/bits/atomic.h (__HAVE_64B_ATOMICS, + USE_ATOMIC_COMPILER_BUILTINS): Likewise. + * sysdeps/x86_64/bits/atomic.h (__HAVE_64B_ATOMICS, + USE_ATOMIC_COMPILER_BUILTINS): Likewise. + 2014-11-19 Roland McGrath * nptl/pthread_create.c (__pthread_create_2_1): Don't try to validate diff --git a/sysdeps/aarch64/bits/atomic.h b/sysdeps/aarch64/bits/atomic.h index 456e2ecdff..a8d3ae721f 100644 --- a/sysdeps/aarch64/bits/atomic.h +++ b/sysdeps/aarch64/bits/atomic.h @@ -36,6 +36,8 @@ typedef uintptr_t uatomicptr_t; typedef intmax_t atomic_max_t; typedef uintmax_t uatomic_max_t; +#define __HAVE_64B_ATOMICS 1 +#define USE_ATOMIC_COMPILER_BUILTINS 1 /* Compare and exchange. For all "bool" routines, we return FALSE if exchange succesful. */ diff --git a/sysdeps/alpha/bits/atomic.h b/sysdeps/alpha/bits/atomic.h index abbbc7c92d..e9275e9982 100644 --- a/sysdeps/alpha/bits/atomic.h +++ b/sysdeps/alpha/bits/atomic.h @@ -42,6 +42,9 @@ typedef uintptr_t uatomicptr_t; typedef intmax_t atomic_max_t; typedef uintmax_t uatomic_max_t; +#define __HAVE_64B_ATOMICS 1 +#define USE_ATOMIC_COMPILER_BUILTINS 0 + #ifdef UP # define __MB /* nothing */ diff --git a/sysdeps/arm/bits/atomic.h b/sysdeps/arm/bits/atomic.h index 88cbe67926..315b4cf603 100644 --- a/sysdeps/arm/bits/atomic.h +++ b/sysdeps/arm/bits/atomic.h @@ -33,6 +33,9 @@ typedef uintptr_t uatomicptr_t; typedef intmax_t atomic_max_t; typedef uintmax_t uatomic_max_t; +#define __HAVE_64B_ATOMICS 0 +#define USE_ATOMIC_COMPILER_BUILTINS 0 + void __arm_link_error (void); #ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 diff --git a/sysdeps/i386/i486/bits/atomic.h b/sysdeps/i386/i486/bits/atomic.h index 76e0e8e2e3..739d3846f2 100644 --- a/sysdeps/i386/i486/bits/atomic.h +++ b/sysdeps/i386/i486/bits/atomic.h @@ -54,6 +54,9 @@ typedef uintmax_t uatomic_max_t; # endif #endif +#define __HAVE_64B_ATOMICS 0 +#define USE_ATOMIC_COMPILER_BUILTINS 0 + #define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \ __sync_val_compare_and_swap (mem, oldval, newval) diff --git a/sysdeps/ia64/bits/atomic.h b/sysdeps/ia64/bits/atomic.h index 766cb4b741..5e090b9072 100644 --- a/sysdeps/ia64/bits/atomic.h +++ b/sysdeps/ia64/bits/atomic.h @@ -43,6 +43,9 @@ typedef uintptr_t uatomicptr_t; typedef intmax_t atomic_max_t; typedef uintmax_t uatomic_max_t; +#define __HAVE_64B_ATOMICS 1 +#define USE_ATOMIC_COMPILER_BUILTINS 0 + #define __arch_compare_and_exchange_bool_8_acq(mem, newval, oldval) \ (abort (), 0) diff --git a/sysdeps/m68k/coldfire/bits/atomic.h b/sysdeps/m68k/coldfire/bits/atomic.h index ec0c59a7da..4851999fca 100644 --- a/sysdeps/m68k/coldfire/bits/atomic.h +++ b/sysdeps/m68k/coldfire/bits/atomic.h @@ -49,6 +49,10 @@ typedef uintptr_t uatomicptr_t; typedef intmax_t atomic_max_t; typedef uintmax_t uatomic_max_t; +/* If we have just non-atomic operations, we can as well make them wide. */ +#define __HAVE_64B_ATOMICS 1 +#define USE_ATOMIC_COMPILER_BUILTINS 0 + /* The only basic operation needed is compare and exchange. */ #define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \ ({ __typeof (mem) __gmemp = (mem); \ diff --git a/sysdeps/m68k/m680x0/m68020/bits/atomic.h b/sysdeps/m68k/m680x0/m68020/bits/atomic.h index 0f081f169a..395bac06b9 100644 --- a/sysdeps/m68k/m680x0/m68020/bits/atomic.h +++ b/sysdeps/m68k/m680x0/m68020/bits/atomic.h @@ -44,6 +44,9 @@ typedef uintptr_t uatomicptr_t; typedef intmax_t atomic_max_t; typedef uintmax_t uatomic_max_t; +#define __HAVE_64B_ATOMICS 1 +#define USE_ATOMIC_COMPILER_BUILTINS 0 + #define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \ ({ __typeof (*(mem)) __ret; \ __asm __volatile ("cas%.b %0,%2,%1" \ diff --git a/sysdeps/microblaze/bits/atomic.h b/sysdeps/microblaze/bits/atomic.h index 77004a0284..395162df2d 100644 --- a/sysdeps/microblaze/bits/atomic.h +++ b/sysdeps/microblaze/bits/atomic.h @@ -35,6 +35,9 @@ typedef uintptr_t uatomicptr_t; typedef intmax_t atomic_max_t; typedef uintmax_t uatomic_max_t; +#define __HAVE_64B_ATOMICS 1 +#define USE_ATOMIC_COMPILER_BUILTINS 0 + /* Microblaze does not have byte and halfword forms of load and reserve and store conditional. So for microblaze we stub out the 8- and 16-bit forms. */ diff --git a/sysdeps/mips/bits/atomic.h b/sysdeps/mips/bits/atomic.h index 35b3786789..091b199bf8 100644 --- a/sysdeps/mips/bits/atomic.h +++ b/sysdeps/mips/bits/atomic.h @@ -44,6 +44,12 @@ typedef uintmax_t uatomic_max_t; #define MIPS_PUSH_MIPS2 #endif +#if _MIPS_SIM == _ABIO32 +#define __HAVE_64B_ATOMICS 0 +#else +#define __HAVE_64B_ATOMICS 1 +#endif + /* See the comments in about the use of the sync instruction. */ #ifndef MIPS_SYNC # define MIPS_SYNC sync @@ -86,6 +92,8 @@ typedef uintmax_t uatomic_max_t; have no assembly alternative available and want to avoid the __sync_* builtins if at all possible. */ +#define USE_ATOMIC_COMPILER_BUILTINS 1 + /* Compare and exchange. For all "bool" routines, we return FALSE if exchange succesful. */ @@ -234,6 +242,8 @@ typedef uintmax_t uatomic_max_t; /* This implementation using inline assembly will be removed once glibc requires GCC 4.8 or later to build. */ +#define USE_ATOMIC_COMPILER_BUILTINS 0 + /* Compare and exchange. For all of the "xxx" routines, we expect a "__prev" and a "__cmp" variable to be provided by the enclosing scope, in which values are returned. */ diff --git a/sysdeps/powerpc/powerpc32/bits/atomic.h b/sysdeps/powerpc/powerpc32/bits/atomic.h index a3dd09cd9a..117b5a0775 100644 --- a/sysdeps/powerpc/powerpc32/bits/atomic.h +++ b/sysdeps/powerpc/powerpc32/bits/atomic.h @@ -33,6 +33,9 @@ # define MUTEX_HINT_REL #endif +#define __HAVE_64B_ATOMICS 0 +#define USE_ATOMIC_COMPILER_BUILTINS 0 + /* * The 32-bit exchange_bool is different on powerpc64 because the subf * does signed 64-bit arithmetic while the lwarx is 32-bit unsigned diff --git a/sysdeps/powerpc/powerpc64/bits/atomic.h b/sysdeps/powerpc/powerpc64/bits/atomic.h index ed26b7253e..5c4ebb6ad5 100644 --- a/sysdeps/powerpc/powerpc64/bits/atomic.h +++ b/sysdeps/powerpc/powerpc64/bits/atomic.h @@ -33,6 +33,9 @@ # define MUTEX_HINT_REL #endif +#define __HAVE_64B_ATOMICS 1 +#define USE_ATOMIC_COMPILER_BUILTINS 0 + /* The 32-bit exchange_bool is different on powerpc64 because the subf does signed 64-bit arithmetic while the lwarx is 32-bit unsigned (a load word and zero (high 32) form) load. diff --git a/sysdeps/s390/bits/atomic.h b/sysdeps/s390/bits/atomic.h index 6824165779..b809b5efaa 100644 --- a/sysdeps/s390/bits/atomic.h +++ b/sysdeps/s390/bits/atomic.h @@ -43,6 +43,8 @@ typedef uintptr_t uatomicptr_t; typedef intmax_t atomic_max_t; typedef uintmax_t uatomic_max_t; +#define USE_ATOMIC_COMPILER_BUILTINS 0 + #define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \ (abort (), (__typeof (*mem)) 0) @@ -59,6 +61,7 @@ typedef uintmax_t uatomic_max_t; __archold; }) #ifdef __s390x__ +# define __HAVE_64B_ATOMICS 1 # define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \ ({ __typeof (mem) __archmem = (mem); \ __typeof (*mem) __archold = (oldval); \ @@ -67,6 +70,7 @@ typedef uintmax_t uatomic_max_t; : "d" ((long) (newval)), "m" (*__archmem) : "cc", "memory" ); \ __archold; }) #else +# define __HAVE_64B_ATOMICS 0 /* For 31 bit we do not really need 64-bit compare-and-exchange. We can implement them by use of the csd instruction. The straightforward implementation causes warnings so we skip the definition for now. */ diff --git a/sysdeps/sparc/sparc32/bits/atomic.h b/sysdeps/sparc/sparc32/bits/atomic.h index 251e65662d..2ae2eaa553 100644 --- a/sysdeps/sparc/sparc32/bits/atomic.h +++ b/sysdeps/sparc/sparc32/bits/atomic.h @@ -47,6 +47,9 @@ typedef uintptr_t uatomicptr_t; typedef intmax_t atomic_max_t; typedef uintmax_t uatomic_max_t; +#define __HAVE_64B_ATOMICS 0 +#define USE_ATOMIC_COMPILER_BUILTINS 0 + /* We have no compare and swap, just test and set. The following implementation contends on 64 global locks diff --git a/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h b/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h index 310e6365e9..7644796da9 100644 --- a/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h +++ b/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h @@ -44,6 +44,9 @@ typedef uintptr_t uatomicptr_t; typedef intmax_t atomic_max_t; typedef uintmax_t uatomic_max_t; +#define __HAVE_64B_ATOMICS 0 +#define USE_ATOMIC_COMPILER_BUILTINS 0 + #define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \ (abort (), (__typeof (*mem)) 0) diff --git a/sysdeps/sparc/sparc64/bits/atomic.h b/sysdeps/sparc/sparc64/bits/atomic.h index d348ed20ae..2bca42b051 100644 --- a/sysdeps/sparc/sparc64/bits/atomic.h +++ b/sysdeps/sparc/sparc64/bits/atomic.h @@ -44,6 +44,9 @@ typedef uintptr_t uatomicptr_t; typedef intmax_t atomic_max_t; typedef uintmax_t uatomic_max_t; +#define __HAVE_64B_ATOMICS 1 +#define USE_ATOMIC_COMPILER_BUILTINS 0 + #define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \ (abort (), (__typeof (*mem)) 0) diff --git a/sysdeps/tile/tilegx/bits/atomic.h b/sysdeps/tile/tilegx/bits/atomic.h index ce12db0216..9aa299f03b 100644 --- a/sysdeps/tile/tilegx/bits/atomic.h +++ b/sysdeps/tile/tilegx/bits/atomic.h @@ -21,6 +21,9 @@ #include +#define __HAVE_64B_ATOMICS 1 +#define USE_ATOMIC_COMPILER_BUILTINS 0 + /* Pick appropriate 8- or 4-byte instruction. */ #define __atomic_update(mem, v, op) \ ((__typeof (*(mem))) (__typeof (*(mem) - *(mem))) \ diff --git a/sysdeps/tile/tilepro/bits/atomic.h b/sysdeps/tile/tilepro/bits/atomic.h index cbbf64cef1..c3865bee2f 100644 --- a/sysdeps/tile/tilepro/bits/atomic.h +++ b/sysdeps/tile/tilepro/bits/atomic.h @@ -21,6 +21,9 @@ #include +#define __HAVE_64B_ATOMICS 0 +#define USE_ATOMIC_COMPILER_BUILTINS 0 + /* 32-bit integer compare-and-exchange. */ static __inline __attribute__ ((always_inline)) int __atomic_cmpxchg_32 (volatile int *mem, int newval, int oldval) diff --git a/sysdeps/unix/sysv/linux/hppa/bits/atomic.h b/sysdeps/unix/sysv/linux/hppa/bits/atomic.h index e55e91b352..b5cdfb6495 100644 --- a/sysdeps/unix/sysv/linux/hppa/bits/atomic.h +++ b/sysdeps/unix/sysv/linux/hppa/bits/atomic.h @@ -44,6 +44,9 @@ typedef uintptr_t uatomicptr_t; typedef intmax_t atomic_max_t; typedef uintmax_t uatomic_max_t; +#define __HAVE_64B_ATOMICS 0 +#define USE_ATOMIC_COMPILER_BUILTINS 0 + /* prev = *addr; if (prev == old) *addr = new; diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/bits/atomic.h b/sysdeps/unix/sysv/linux/m68k/coldfire/bits/atomic.h index cd9bae324e..a8d4a33d5a 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/bits/atomic.h +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/bits/atomic.h @@ -36,6 +36,9 @@ typedef uintptr_t uatomicptr_t; typedef intmax_t atomic_max_t; typedef uintmax_t uatomic_max_t; +#define __HAVE_64B_ATOMICS 0 +#define USE_ATOMIC_COMPILER_BUILTINS 0 + /* The only basic operation needed is compare and exchange. */ /* For ColdFire we'll have to trap into the kernel mode anyway, so trap from the library rather then from the kernel wrapper. */ diff --git a/sysdeps/unix/sysv/linux/sh/bits/atomic.h b/sysdeps/unix/sysv/linux/sh/bits/atomic.h index e819412007..6508c33342 100644 --- a/sysdeps/unix/sysv/linux/sh/bits/atomic.h +++ b/sysdeps/unix/sysv/linux/sh/bits/atomic.h @@ -44,6 +44,9 @@ typedef uintptr_t uatomicptr_t; typedef intmax_t atomic_max_t; typedef uintmax_t uatomic_max_t; +#define __HAVE_64B_ATOMICS 0 +#define USE_ATOMIC_COMPILER_BUILTINS 0 + /* SH kernel has implemented a gUSA ("g" User Space Atomicity) support for the user space atomicity. The atomicity macros use this scheme. diff --git a/sysdeps/x86_64/bits/atomic.h b/sysdeps/x86_64/bits/atomic.h index 4d19ef0bb4..99dfb50295 100644 --- a/sysdeps/x86_64/bits/atomic.h +++ b/sysdeps/x86_64/bits/atomic.h @@ -55,6 +55,12 @@ typedef uintmax_t uatomic_max_t; # endif #endif +#define __HAVE_64B_ATOMICS 1 +#if __GNUC_PREREQ (4, 7) +#define USE_ATOMIC_COMPILER_BUILTINS 1 +#else +#define USE_ATOMIC_COMPILER_BUILTINS 0 +#endif #define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \ __sync_val_compare_and_swap (mem, oldval, newval)