From patchwork Wed Nov 13 19:28:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 179344 Delivered-To: patch@linaro.org Received: by 2002:a92:38d5:0:0:0:0:0 with SMTP id g82csp10039477ilf; Wed, 13 Nov 2019 11:28:55 -0800 (PST) X-Google-Smtp-Source: APXvYqyJ8drMW/LyobPjkqr83L7KPs6/QblpdGykm21izE7h9aa9i8K3U8i63Xlx32XR8XPx5MAB X-Received: by 2002:a17:906:c789:: with SMTP id cw9mr4652520ejb.40.1573673335805; Wed, 13 Nov 2019 11:28:55 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1573673335; cv=none; d=google.com; s=arc-20160816; b=H/JWi0IaNsAG6XkQvbJUHJF1VQ0xw9FXOxl6O9dQDfZ7OYMUIJNMUW486nMIO0YDMc OlLOeweenLwjeDKNP1gSfoqP+WW+/O2/lNTrrhbWBy4gJlnjUlU2BFPaqY1xGchmhMZv 94wuw5+vadGsXJXyOqBBMOE0wF4yPrcFu15WqndVMsLnwM+Wc0vJGnqfq+SuqjjIPV8/ Mn78bAV+WltfsPym6eJaTKOrP2gHEtlQbrMlxbYqPCeEjfFp8d2hUyIFduvgMeNVy132 RdBtXqgIc0xYtEDssKv6A7ff2dA1h7+L1S11HezLU4ooU7Lw5ZS4D3ezYPZ0TLWb+YwY clQA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:delivered-to:sender:list-help:list-post:list-archive :list-subscribe:list-unsubscribe:list-id:precedence:mailing-list :dkim-signature:domainkey-signature; bh=6hg/HdEH5M/gPaDvvOvkXmdVMVRmqSeaxBmnNcnELfg=; b=aeO0Y5hwjg+rcfaFds7Lg51suA7i030YN7eW/m6glgaoi5UwUl7CAfox6JJbWdcUcS JBTrsAJALgKbhxEcJ4LdYBbv8yUcQq1EOuKlz+v9LZXcXSEdHCNgIdCT2uLDFdAMl8pg Qx1+4YOr7G6EJ7i0tSrGjqC3aFANrbtwUfaHOcioHzZZ9pQFF59X3VlIVFOU9aqyPyQX hi62ambAZMId8CjiL3eWXssZ1oMIzfM/4MNZ+v7wQWB6OptUSuyTmg2Tp4DOBfh8NkpS nfReMJ4fthWWnPgH2aZck6HdrbUUVq8SwRT9VVkzwQ2iRqfAhEyqsqBnaMSEBEOOTGpt hVrQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=SLcXsWcK; dkim=pass header.i=@linaro.org header.s=google header.b=D5cGI5Q3; spf=pass (google.com: domain of libc-alpha-return-107056-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-107056-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id y16si1811643ejw.142.2019.11.13.11.28.54 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 13 Nov 2019 11:28:55 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-107056-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=SLcXsWcK; dkim=pass header.i=@linaro.org header.s=google header.b=D5cGI5Q3; spf=pass (google.com: domain of libc-alpha-return-107056-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-107056-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=R8HFk724+r10uIebdVhNpZxoK28f8kY xoi7roHtGBNFAB6eu1tBU9Xi4zFlLvkA7t0duuFNOHi1tWRXZs92K1qh70Cc2SLw suCeIGHD5eOhsjfr583YQwk3wlx+VwZtJDzzkaOnuotPKUEZBT8SioMzVzODPw/o eGVpyRd1AXVc= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id:in-reply-to :references; s=default; bh=disERR676mm+xAcJZdyrU1lK3b0=; b=SLcXs WcKolp4WHorb+J20bDQA9omXqHccEGmo4MdrfD74xQCNuyKWuREjZgU+3D6ovNE2 3/w3wF+qNCaJD1cMfcCX7AOBN3d9jDgfRZ0SVWkBxNlrLwlFMFtcthgtrdf4hz7T PHPRwiV+fFwkXwCywG1ZebdlFSkx/72RND6nio= Received: (qmail 71304 invoked by alias); 13 Nov 2019 19:28:42 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 71294 invoked by uid 89); 13 Nov 2019 19:28:41 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-21.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, SPF_PASS autolearn=ham version=3.3.1 spammy=H*MI:sk:a9e59b0, H*f:sk:a9e59b0, HX-HELO:sk:mail-qv, sk:sparc64 X-HELO: mail-qv1-f54.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=6hg/HdEH5M/gPaDvvOvkXmdVMVRmqSeaxBmnNcnELfg=; b=D5cGI5Q3nq8d+oZOL6RTAw+w112/y1iXaqhBSEMr81852vkx6LKHXckqO9AFyOFuyF sBat5DZ8kD1Cvz5HOdRrU8PqsuezjDFaoizGioZLZ1H2JXnJE+lhWIXZo68mrYqRjRXR VvF+p0PzVP99tEpkuQxmWz3nHXMV43uSB5WtjxvoWsXXeUf4cXlHe1tUJoRYdmTixXxw 10apNFkUuTNJF/48m+QUFdwtEPZseMddF6XPQUOFvlI80q0i/E2JmGBLm6dBmeKS/PHi kcLhSONFOKGrbQpJL0PE3FiYH+5UT51DTCalzIC8wYOxl5Hq/Fnhh9RR48Vl6AtyFWg6 P0HQ== Return-Path: From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Romain Naour , Andreas Larsson Subject: [PATCH 2/2] sparc: Use atomic compiler builtins on sparc Date: Wed, 13 Nov 2019 16:28:23 -0300 Message-Id: <20191113192823.17109-2-adhemerval.zanella@linaro.org> In-Reply-To: <20191113192823.17109-1-adhemerval.zanella@linaro.org> References: <20191113192823.17109-1-adhemerval.zanella@linaro.org> This patch removes the arch-specific atomic instruction, relying on compiler builtins. The __sparc32_atomic_locks support is removed and a configure check is added to check if compiler uses libatomic to implement CAS. It also removes the sparc specific sem_* and pthread_barrier_* implementations. It in turn allows buidling against a LEON3/LEON4 sparcv8 target, although it will still be incompatible with generic sparcv9. Checked on sparcv9-linux-gnu and sparc64-linux-gnu. I also checked with build against sparcv8-linux-gnu with -mcpu=leon3. --- sysdeps/sparc/Makefile | 9 + sysdeps/sparc/atomic-machine.h | 96 +++++ sysdeps/sparc/{sparc64 => }/cpu_relax.c | 4 +- sysdeps/sparc/sparc32/atomic-machine.h | 363 ------------------ sysdeps/sparc/sparc32/configure | 35 ++ sysdeps/sparc/sparc32/configure.ac | 24 ++ sysdeps/sparc/sparc32/lowlevellock.c | 53 --- sysdeps/sparc/sparc32/pthread_barrier_wait.c | 1 - sysdeps/sparc/sparc32/sem_post.c | 82 ---- sysdeps/sparc/sparc32/sem_waitcommon.c | 146 ------- sysdeps/sparc/sparc32/sparcv9/Makefile | 9 - .../sparc/sparc32/sparcv9/atomic-machine.h | 108 ------ sysdeps/sparc/sparc32/sparcv9/cpu_relax.c | 1 - sysdeps/sparc/sparc64/Makefile | 9 - sysdeps/sparc/sparc64/atomic-machine.h | 129 ------- sysdeps/unix/sysv/linux/sparc/lowlevellock.h | 130 ------- 16 files changed, 167 insertions(+), 1032 deletions(-) create mode 100644 sysdeps/sparc/atomic-machine.h rename sysdeps/sparc/{sparc64 => }/cpu_relax.c (92%) delete mode 100644 sysdeps/sparc/sparc32/atomic-machine.h delete mode 100644 sysdeps/sparc/sparc32/lowlevellock.c delete mode 100644 sysdeps/sparc/sparc32/pthread_barrier_wait.c delete mode 100644 sysdeps/sparc/sparc32/sem_post.c delete mode 100644 sysdeps/sparc/sparc32/sem_waitcommon.c delete mode 100644 sysdeps/sparc/sparc32/sparcv9/atomic-machine.h delete mode 100644 sysdeps/sparc/sparc32/sparcv9/cpu_relax.c delete mode 100644 sysdeps/sparc/sparc64/atomic-machine.h delete mode 100644 sysdeps/unix/sysv/linux/sparc/lowlevellock.h -- 2.17.1 Tested-by: Andreas Larsson diff --git a/sysdeps/sparc/Makefile b/sysdeps/sparc/Makefile index 3f0c096400..38b33af6e0 100644 --- a/sysdeps/sparc/Makefile +++ b/sysdeps/sparc/Makefile @@ -16,5 +16,14 @@ CPPFLAGS-crti.S += -fPIC CPPFLAGS-crtn.S += -fPIC endif +# nscd uses atomic_spin_nop which in turn requires cpu_relax +ifeq ($(subdir),nscd) +routines += cpu_relax +endif + +ifeq ($(subdir), nptl) +libpthread-routines += cpu_relax +endif + # The assembler on SPARC needs the -fPIC flag even when it's assembler code. ASFLAGS-.os += -fPIC diff --git a/sysdeps/sparc/atomic-machine.h b/sysdeps/sparc/atomic-machine.h new file mode 100644 index 0000000000..e0bb9b61b9 --- /dev/null +++ b/sysdeps/sparc/atomic-machine.h @@ -0,0 +1,96 @@ +/* Atomic operations. sparc32 version. + Copyright (C) 2003-2019 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek , 2003. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _ATOMIC_MACHINE_H +#define _ATOMIC_MACHINE_H 1 + +#include + +typedef int8_t atomic8_t; +typedef uint8_t uatomic8_t; +typedef int_fast8_t atomic_fast8_t; +typedef uint_fast8_t uatomic_fast8_t; + +typedef int16_t atomic16_t; +typedef uint16_t uatomic16_t; +typedef int_fast16_t atomic_fast16_t; +typedef uint_fast16_t uatomic_fast16_t; + +typedef int32_t atomic32_t; +typedef uint32_t uatomic32_t; +typedef int_fast32_t atomic_fast32_t; +typedef uint_fast32_t uatomic_fast32_t; + +typedef int64_t atomic64_t; +typedef uint64_t uatomic64_t; +typedef int_fast64_t atomic_fast64_t; +typedef uint_fast64_t uatomic_fast64_t; + +typedef intptr_t atomicptr_t; +typedef uintptr_t uatomicptr_t; +typedef intmax_t atomic_max_t; +typedef uintmax_t uatomic_max_t; + +#ifdef __arch64__ +# define __HAVE_64B_ATOMICS 1 +#else +# define __HAVE_64B_ATOMICS 0 +#endif +#define USE_ATOMIC_COMPILER_BUILTINS 1 + +/* XXX Is this actually correct? */ +#define ATOMIC_EXCHANGE_USES_CAS __HAVE_64B_ATOMICS + +/* Compare and exchange. + For all "bool" routines, we return FALSE if exchange succesful. */ + +#define __arch_compare_and_exchange_val_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + __oldval; \ + }) + +#define atomic_compare_and_exchange_val_acq(mem, new, old) \ + ({ \ + __typeof ((__typeof (*(mem))) *(mem)) __result; \ + if (sizeof (*mem) == 4 \ + || (__HAVE_64B_ATOMICS && sizeof (*mem) == 8)) \ + __result = __arch_compare_and_exchange_val_int (mem, new, old, \ + __ATOMIC_ACQUIRE); \ + else \ + abort (); \ + __result; \ + }) + +#ifdef __sparc_v9__ +# define atomic_full_barrier() \ + __asm __volatile ("membar #LoadLoad | #LoadStore" \ + " | #StoreLoad | #StoreStore" : : : "memory") +# define atomic_read_barrier() \ + __asm __volatile ("membar #LoadLoad | #LoadStore" : : : "memory") +# define atomic_write_barrier() \ + __asm __volatile ("membar #LoadStore | #StoreStore" : : : "memory") + +extern void __cpu_relax (void); +# define atomic_spin_nop() __cpu_relax () +#endif + +#endif /* _ATOMIC_MACHINE_H */ diff --git a/sysdeps/sparc/sparc64/cpu_relax.c b/sysdeps/sparc/cpu_relax.c similarity index 92% rename from sysdeps/sparc/sparc64/cpu_relax.c rename to sysdeps/sparc/cpu_relax.c index b86afdec2c..973dfb5935 100644 --- a/sysdeps/sparc/sparc64/cpu_relax.c +++ b/sysdeps/sparc/cpu_relax.c @@ -1,4 +1,4 @@ -/* CPU strand yielding for busy loops. Linux/sparc64 version. +/* CPU strand yielding for busy loops. Linux/sparc version. Copyright (C) 2017-2019 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -18,6 +18,7 @@ #include +#ifdef __sparc_v9__ static void __cpu_relax_generic (void) { @@ -36,3 +37,4 @@ sparc_libc_ifunc (__cpu_relax, hwcap & HWCAP_SPARC_PAUSE ? __cpu_relax_pause : __cpu_relax_generic) +#endif diff --git a/sysdeps/sparc/sparc32/atomic-machine.h b/sysdeps/sparc/sparc32/atomic-machine.h deleted file mode 100644 index d82a4f4ecc..0000000000 --- a/sysdeps/sparc/sparc32/atomic-machine.h +++ /dev/null @@ -1,363 +0,0 @@ -/* Atomic operations. sparc32 version. - Copyright (C) 2003-2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek , 2003. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifndef _ATOMIC_MACHINE_H -#define _ATOMIC_MACHINE_H 1 - -#include - -typedef int8_t atomic8_t; -typedef uint8_t uatomic8_t; -typedef int_fast8_t atomic_fast8_t; -typedef uint_fast8_t uatomic_fast8_t; - -typedef int16_t atomic16_t; -typedef uint16_t uatomic16_t; -typedef int_fast16_t atomic_fast16_t; -typedef uint_fast16_t uatomic_fast16_t; - -typedef int32_t atomic32_t; -typedef uint32_t uatomic32_t; -typedef int_fast32_t atomic_fast32_t; -typedef uint_fast32_t uatomic_fast32_t; - -typedef int64_t atomic64_t; -typedef uint64_t uatomic64_t; -typedef int_fast64_t atomic_fast64_t; -typedef uint_fast64_t uatomic_fast64_t; - -typedef intptr_t atomicptr_t; -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 - -/* XXX Is this actually correct? */ -#define ATOMIC_EXCHANGE_USES_CAS 1 - - -/* We have no compare and swap, just test and set. - The following implementation contends on 64 global locks - per library and assumes no variable will be accessed using atomic.h - macros from two different libraries. */ - -__make_section_unallocated - (".gnu.linkonce.b.__sparc32_atomic_locks, \"aw\", %nobits"); - -volatile unsigned char __sparc32_atomic_locks[64] - __attribute__ ((nocommon, section (".gnu.linkonce.b.__sparc32_atomic_locks" - __sec_comment), - visibility ("hidden"))); - -#define __sparc32_atomic_do_lock(addr) \ - do \ - { \ - unsigned int __old_lock; \ - unsigned int __idx = (((long) addr >> 2) ^ ((long) addr >> 12)) \ - & 63; \ - do \ - __asm __volatile ("ldstub %1, %0" \ - : "=r" (__old_lock), \ - "=m" (__sparc32_atomic_locks[__idx]) \ - : "m" (__sparc32_atomic_locks[__idx]) \ - : "memory"); \ - while (__old_lock); \ - } \ - while (0) - -#define __sparc32_atomic_do_unlock(addr) \ - do \ - { \ - __sparc32_atomic_locks[(((long) addr >> 2) \ - ^ ((long) addr >> 12)) & 63] = 0; \ - __asm __volatile ("" ::: "memory"); \ - } \ - while (0) - -#define __sparc32_atomic_do_lock24(addr) \ - do \ - { \ - unsigned int __old_lock; \ - do \ - __asm __volatile ("ldstub %1, %0" \ - : "=r" (__old_lock), "=m" (*(addr)) \ - : "m" (*(addr)) \ - : "memory"); \ - while (__old_lock); \ - } \ - while (0) - -#define __sparc32_atomic_do_unlock24(addr) \ - do \ - { \ - __asm __volatile ("" ::: "memory"); \ - *(char *) (addr) = 0; \ - } \ - while (0) - - -#ifndef SHARED -# define __v9_compare_and_exchange_val_32_acq(mem, newval, oldval) \ -({union { __typeof (oldval) a; uint32_t v; } oldval_arg = { .a = (oldval) }; \ - union { __typeof (newval) a; uint32_t v; } newval_arg = { .a = (newval) }; \ - register uint32_t __acev_tmp __asm ("%g6"); \ - register __typeof (mem) __acev_mem __asm ("%g1") = (mem); \ - register uint32_t __acev_oldval __asm ("%g5"); \ - __acev_tmp = newval_arg.v; \ - __acev_oldval = oldval_arg.v; \ - /* .word 0xcde05005 is cas [%g1], %g5, %g6. Can't use cas here though, \ - because as will then mark the object file as V8+ arch. */ \ - __asm __volatile (".word 0xcde05005" \ - : "+r" (__acev_tmp), "=m" (*__acev_mem) \ - : "r" (__acev_oldval), "m" (*__acev_mem), \ - "r" (__acev_mem) : "memory"); \ - (__typeof (oldval)) __acev_tmp; }) -#endif - -/* The only basic operation needed is compare and exchange. */ -#define __v7_compare_and_exchange_val_acq(mem, newval, oldval) \ - ({ __typeof (mem) __acev_memp = (mem); \ - __typeof (*mem) __acev_ret; \ - __typeof (*mem) __acev_newval = (newval); \ - \ - __sparc32_atomic_do_lock (__acev_memp); \ - __acev_ret = *__acev_memp; \ - if (__acev_ret == (oldval)) \ - *__acev_memp = __acev_newval; \ - __sparc32_atomic_do_unlock (__acev_memp); \ - __acev_ret; }) - -#define __v7_compare_and_exchange_bool_acq(mem, newval, oldval) \ - ({ __typeof (mem) __aceb_memp = (mem); \ - int __aceb_ret; \ - __typeof (*mem) __aceb_newval = (newval); \ - \ - __sparc32_atomic_do_lock (__aceb_memp); \ - __aceb_ret = 0; \ - if (*__aceb_memp == (oldval)) \ - *__aceb_memp = __aceb_newval; \ - else \ - __aceb_ret = 1; \ - __sparc32_atomic_do_unlock (__aceb_memp); \ - __aceb_ret; }) - -#define __v7_exchange_acq(mem, newval) \ - ({ __typeof (mem) __acev_memp = (mem); \ - __typeof (*mem) __acev_ret; \ - __typeof (*mem) __acev_newval = (newval); \ - \ - __sparc32_atomic_do_lock (__acev_memp); \ - __acev_ret = *__acev_memp; \ - *__acev_memp = __acev_newval; \ - __sparc32_atomic_do_unlock (__acev_memp); \ - __acev_ret; }) - -#define __v7_exchange_and_add(mem, value) \ - ({ __typeof (mem) __acev_memp = (mem); \ - __typeof (*mem) __acev_ret; \ - \ - __sparc32_atomic_do_lock (__acev_memp); \ - __acev_ret = *__acev_memp; \ - *__acev_memp = __acev_ret + (value); \ - __sparc32_atomic_do_unlock (__acev_memp); \ - __acev_ret; }) - -/* Special versions, which guarantee that top 8 bits of all values - are cleared and use those bits as the ldstub lock. */ -#define __v7_compare_and_exchange_val_24_acq(mem, newval, oldval) \ - ({ __typeof (mem) __acev_memp = (mem); \ - __typeof (*mem) __acev_ret; \ - __typeof (*mem) __acev_newval = (newval); \ - \ - __sparc32_atomic_do_lock24 (__acev_memp); \ - __acev_ret = *__acev_memp & 0xffffff; \ - if (__acev_ret == (oldval)) \ - *__acev_memp = __acev_newval; \ - else \ - __sparc32_atomic_do_unlock24 (__acev_memp); \ - __asm __volatile ("" ::: "memory"); \ - __acev_ret; }) - -#define __v7_exchange_24_rel(mem, newval) \ - ({ __typeof (mem) __acev_memp = (mem); \ - __typeof (*mem) __acev_ret; \ - __typeof (*mem) __acev_newval = (newval); \ - \ - __sparc32_atomic_do_lock24 (__acev_memp); \ - __acev_ret = *__acev_memp & 0xffffff; \ - *__acev_memp = __acev_newval; \ - __asm __volatile ("" ::: "memory"); \ - __acev_ret; }) - -#ifdef SHARED - -/* When dynamically linked, we assume pre-v9 libraries are only ever - used on pre-v9 CPU. */ -# define __atomic_is_v9 0 - -# define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \ - __v7_compare_and_exchange_val_acq (mem, newval, oldval) - -# define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \ - __v7_compare_and_exchange_bool_acq (mem, newval, oldval) - -# define atomic_exchange_acq(mem, newval) \ - __v7_exchange_acq (mem, newval) - -# define atomic_exchange_and_add(mem, value) \ - __v7_exchange_and_add (mem, value) - -# define atomic_compare_and_exchange_val_24_acq(mem, newval, oldval) \ - ({ \ - if (sizeof (*mem) != 4) \ - abort (); \ - __v7_compare_and_exchange_val_24_acq (mem, newval, oldval); }) - -# define atomic_exchange_24_rel(mem, newval) \ - ({ \ - if (sizeof (*mem) != 4) \ - abort (); \ - __v7_exchange_24_rel (mem, newval); }) - -# define atomic_full_barrier() __asm ("" ::: "memory") -# define atomic_read_barrier() atomic_full_barrier () -# define atomic_write_barrier() atomic_full_barrier () - -#else - -/* In libc.a/libpthread.a etc. we don't know if we'll be run on - pre-v9 or v9 CPU. To be interoperable with dynamically linked - apps on v9 CPUs e.g. with process shared primitives, use cas insn - on v9 CPUs and ldstub on pre-v9. */ - -extern uint64_t _dl_hwcap __attribute__((weak)); -# define __atomic_is_v9 \ - (__builtin_expect (&_dl_hwcap != 0, 1) \ - && __builtin_expect (_dl_hwcap & HWCAP_SPARC_V9, HWCAP_SPARC_V9)) - -# define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \ - ({ \ - __typeof (*mem) __acev_wret; \ - if (sizeof (*mem) != 4) \ - abort (); \ - if (__atomic_is_v9) \ - __acev_wret \ - = __v9_compare_and_exchange_val_32_acq (mem, newval, oldval);\ - else \ - __acev_wret \ - = __v7_compare_and_exchange_val_acq (mem, newval, oldval); \ - __acev_wret; }) - -# define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \ - ({ \ - int __acev_wret; \ - if (sizeof (*mem) != 4) \ - abort (); \ - if (__atomic_is_v9) \ - { \ - __typeof (oldval) __acev_woldval = (oldval); \ - __acev_wret \ - = __v9_compare_and_exchange_val_32_acq (mem, newval, \ - __acev_woldval) \ - != __acev_woldval; \ - } \ - else \ - __acev_wret \ - = __v7_compare_and_exchange_bool_acq (mem, newval, oldval); \ - __acev_wret; }) - -# define atomic_exchange_rel(mem, newval) \ - ({ \ - __typeof (*mem) __acev_wret; \ - if (sizeof (*mem) != 4) \ - abort (); \ - if (__atomic_is_v9) \ - { \ - __typeof (mem) __acev_wmemp = (mem); \ - __typeof (*(mem)) __acev_wval = (newval); \ - do \ - __acev_wret = *__acev_wmemp; \ - while (__builtin_expect \ - (__v9_compare_and_exchange_val_32_acq (__acev_wmemp,\ - __acev_wval, \ - __acev_wret) \ - != __acev_wret, 0)); \ - } \ - else \ - __acev_wret = __v7_exchange_acq (mem, newval); \ - __acev_wret; }) - -# define atomic_compare_and_exchange_val_24_acq(mem, newval, oldval) \ - ({ \ - __typeof (*mem) __acev_wret; \ - if (sizeof (*mem) != 4) \ - abort (); \ - if (__atomic_is_v9) \ - __acev_wret \ - = __v9_compare_and_exchange_val_32_acq (mem, newval, oldval);\ - else \ - __acev_wret \ - = __v7_compare_and_exchange_val_24_acq (mem, newval, oldval);\ - __acev_wret; }) - -# define atomic_exchange_24_rel(mem, newval) \ - ({ \ - __typeof (*mem) __acev_w24ret; \ - if (sizeof (*mem) != 4) \ - abort (); \ - if (__atomic_is_v9) \ - __acev_w24ret = atomic_exchange_rel (mem, newval); \ - else \ - __acev_w24ret = __v7_exchange_24_rel (mem, newval); \ - __acev_w24ret; }) - -#define atomic_full_barrier() \ - do { \ - if (__atomic_is_v9) \ - /* membar #LoadLoad | #LoadStore | #StoreLoad | #StoreStore */ \ - __asm __volatile (".word 0x8143e00f" : : : "memory"); \ - else \ - __asm __volatile ("" : : : "memory"); \ - } while (0) - -#define atomic_read_barrier() \ - do { \ - if (__atomic_is_v9) \ - /* membar #LoadLoad | #LoadStore */ \ - __asm __volatile (".word 0x8143e005" : : : "memory"); \ - else \ - __asm __volatile ("" : : : "memory"); \ - } while (0) - -#define atomic_write_barrier() \ - do { \ - if (__atomic_is_v9) \ - /* membar #LoadStore | #StoreStore */ \ - __asm __volatile (".word 0x8143e00c" : : : "memory"); \ - else \ - __asm __volatile ("" : : : "memory"); \ - } while (0) - -#endif - -#include - -#endif /* atomic-machine.h */ diff --git a/sysdeps/sparc/sparc32/configure b/sysdeps/sparc/sparc32/configure index 337531fe94..98f94991dc 100644 --- a/sysdeps/sparc/sparc32/configure +++ b/sysdeps/sparc/sparc32/configure @@ -160,3 +160,38 @@ $as_echo "$libc_cv_sparcv8" >&6; } if test $libc_cv_sparcv8 = no; then as_fn_error $? "no support for pre-v8 sparc" "$LINENO" 5 fi + +# Test if compiler generates external calls to libatomic for CAS operation. +# It is suffice to check for int only and the test is similar of C11 +# atomic_compare_exchange_strong using GCC builtins. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for external libatomic calls" >&5 +$as_echo_n "checking for external libatomic calls... " >&6; } +if ${libc_cv_uses_libatomic+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat > conftest.c <&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + if grep '__atomic_compare_exchange_4' conftest.s >/dev/null; then + libc_cv_use_libatomic=yes + fi + fi + rm -f conftest.c conftest.s + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_uses_libatomic" >&5 +$as_echo "$libc_cv_uses_libatomic" >&6; } +if test $libc_cv_use_libatomic = yes; then + as_fn_error $? "external dependency of libatomic is not supported" "$LINENO" 5 +fi diff --git a/sysdeps/sparc/sparc32/configure.ac b/sysdeps/sparc/sparc32/configure.ac index 99229bfadb..38909c2934 100644 --- a/sysdeps/sparc/sparc32/configure.ac +++ b/sysdeps/sparc/sparc32/configure.ac @@ -11,3 +11,27 @@ AC_CACHE_CHECK([for at least sparcv8 support], if test $libc_cv_sparcv8 = no; then AC_MSG_ERROR([no support for pre-v8 sparc]) fi + +# Test if compiler generates external calls to libatomic for CAS operation. +# It is suffice to check for int only and the test is similar of C11 +# atomic_compare_exchange_strong using GCC builtins. +AC_CACHE_CHECK(for external libatomic calls, + libc_cv_uses_libatomic, + [cat > conftest.c <&AS_MESSAGE_LOG_FD); then + if grep '__atomic_compare_exchange_4' conftest.s >/dev/null; then + libc_cv_use_libatomic=yes + fi + fi + rm -f conftest.c conftest.s + ]) +if test $libc_cv_use_libatomic = yes; then + AC_MSG_ERROR([external dependency of libatomic is not supported]) +fi diff --git a/sysdeps/sparc/sparc32/lowlevellock.c b/sysdeps/sparc/sparc32/lowlevellock.c deleted file mode 100644 index 1a0ab4d9f2..0000000000 --- a/sysdeps/sparc/sparc32/lowlevellock.c +++ /dev/null @@ -1,53 +0,0 @@ -/* low level locking for pthread library. SPARC version. - Copyright (C) 2003-2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Paul Mackerras , 2003. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include -#include -#include - - -void -__lll_lock_wait_private (int *futex) -{ - do - { - int oldval = atomic_compare_and_exchange_val_24_acq (futex, 2, 1); - if (oldval != 0) - lll_futex_wait (futex, 2, LLL_PRIVATE); - } - while (atomic_compare_and_exchange_val_24_acq (futex, 2, 0) != 0); -} - - -/* These functions don't get included in libc.so */ -#if IS_IN (libpthread) -void -__lll_lock_wait (int *futex, int private) -{ - do - { - int oldval = atomic_compare_and_exchange_val_24_acq (futex, 2, 1); - if (oldval != 0) - lll_futex_wait (futex, 2, private); - } - while (atomic_compare_and_exchange_val_24_acq (futex, 2, 0) != 0); -} -#endif diff --git a/sysdeps/sparc/sparc32/pthread_barrier_wait.c b/sysdeps/sparc/sparc32/pthread_barrier_wait.c deleted file mode 100644 index e5ef911f62..0000000000 --- a/sysdeps/sparc/sparc32/pthread_barrier_wait.c +++ /dev/null @@ -1 +0,0 @@ -#error No support for pthread barriers on pre-v9 sparc. diff --git a/sysdeps/sparc/sparc32/sem_post.c b/sysdeps/sparc/sparc32/sem_post.c deleted file mode 100644 index 5389725f83..0000000000 --- a/sysdeps/sparc/sparc32/sem_post.c +++ /dev/null @@ -1,82 +0,0 @@ -/* sem_post -- post to a POSIX semaphore. Generic futex-using version. - Copyright (C) 2003-2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek , 2003. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include -#include -#include -#include -#include - -#include - - -/* See sem_wait for an explanation of the algorithm. */ -int -__new_sem_post (sem_t *sem) -{ - struct new_sem *isem = (struct new_sem *) sem; - int private = isem->private; - unsigned int v; - - __sparc32_atomic_do_lock24 (&isem->pad); - - v = isem->value; - if ((v >> SEM_VALUE_SHIFT) == SEM_VALUE_MAX) - { - __sparc32_atomic_do_unlock24 (&isem->pad); - - __set_errno (EOVERFLOW); - return -1; - } - isem->value = v + (1 << SEM_VALUE_SHIFT); - - __sparc32_atomic_do_unlock24 (&isem->pad); - - if ((v & SEM_NWAITERS_MASK) != 0) - futex_wake (&isem->value, 1, private); - - return 0; -} -versioned_symbol (libpthread, __new_sem_post, sem_post, GLIBC_2_1); - - -#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1) -int -attribute_compat_text_section -__old_sem_post (sem_t *sem) -{ - int *futex = (int *) sem; - - /* We must need to synchronize with consumers of this token, so the atomic - increment must have release MO semantics. */ - atomic_write_barrier (); - (void) atomic_increment_val (futex); - /* We always have to assume it is a shared semaphore. */ - int err = lll_futex_wake (futex, 1, LLL_SHARED); - if (__builtin_expect (err, 0) < 0) - { - __set_errno (-err); - return -1; - } - return 0; -} -compat_symbol (libpthread, __old_sem_post, sem_post, GLIBC_2_0); -#endif diff --git a/sysdeps/sparc/sparc32/sem_waitcommon.c b/sysdeps/sparc/sparc32/sem_waitcommon.c deleted file mode 100644 index 907101bb06..0000000000 --- a/sysdeps/sparc/sparc32/sem_waitcommon.c +++ /dev/null @@ -1,146 +0,0 @@ -/* sem_waitcommon -- wait on a semaphore, shared code. - Copyright (C) 2003-2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Paul Mackerras , 2003. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - - -static void -__sem_wait_32_finish (struct new_sem *sem); - -static void -__sem_wait_cleanup (void *arg) -{ - struct new_sem *sem = (struct new_sem *) arg; - - __sem_wait_32_finish (sem); -} - -/* Wait until at least one token is available, possibly with a timeout. - This is in a separate function in order to make sure gcc - puts the call site into an exception region, and thus the - cleanups get properly run. TODO still necessary? Other futex_wait - users don't seem to need it. */ -static int -__attribute__ ((noinline)) -do_futex_wait (struct new_sem *sem, const struct timespec *abstime) -{ - int err; - - err = futex_abstimed_wait_cancelable (&sem->value, SEM_NWAITERS_MASK, - abstime, sem->private); - - return err; -} - -/* Fast path: Try to grab a token without blocking. */ -static int -__new_sem_wait_fast (struct new_sem *sem, int definitive_result) -{ - unsigned int v; - int ret = 0; - - __sparc32_atomic_do_lock24(&sem->pad); - - v = sem->value; - if ((v >> SEM_VALUE_SHIFT) == 0) - ret = -1; - else - sem->value = v - (1 << SEM_VALUE_SHIFT); - - __sparc32_atomic_do_unlock24(&sem->pad); - - return ret; -} - -/* Slow path that blocks. */ -static int -__attribute__ ((noinline)) -__new_sem_wait_slow (struct new_sem *sem, const struct timespec *abstime) -{ - unsigned int v; - int err = 0; - - __sparc32_atomic_do_lock24(&sem->pad); - - sem->nwaiters++; - - pthread_cleanup_push (__sem_wait_cleanup, sem); - - /* Wait for a token to be available. Retry until we can grab one. */ - v = sem->value; - do - { - if (!(v & SEM_NWAITERS_MASK)) - sem->value = v | SEM_NWAITERS_MASK; - - /* If there is no token, wait. */ - if ((v >> SEM_VALUE_SHIFT) == 0) - { - __sparc32_atomic_do_unlock24(&sem->pad); - - err = do_futex_wait(sem, abstime); - if (err == ETIMEDOUT || err == EINTR) - { - __set_errno (err); - err = -1; - goto error; - } - err = 0; - - __sparc32_atomic_do_lock24(&sem->pad); - - /* We blocked, so there might be a token now. */ - v = sem->value; - } - } - /* If there is no token, we must not try to grab one. */ - while ((v >> SEM_VALUE_SHIFT) == 0); - - sem->value = v - (1 << SEM_VALUE_SHIFT); - - __sparc32_atomic_do_unlock24(&sem->pad); - -error: - pthread_cleanup_pop (0); - - __sem_wait_32_finish (sem); - - return err; -} - -/* Stop being a registered waiter (non-64b-atomics code only). */ -static void -__sem_wait_32_finish (struct new_sem *sem) -{ - __sparc32_atomic_do_lock24(&sem->pad); - - if (--sem->nwaiters == 0) - sem->value &= ~SEM_NWAITERS_MASK; - - __sparc32_atomic_do_unlock24(&sem->pad); -} diff --git a/sysdeps/sparc/sparc32/sparcv9/Makefile b/sysdeps/sparc/sparc32/sparcv9/Makefile index 45507eabdb..c49b3bea99 100644 --- a/sysdeps/sparc/sparc32/sparcv9/Makefile +++ b/sysdeps/sparc/sparc32/sparcv9/Makefile @@ -4,12 +4,3 @@ ASFLAGS-.o += -Wa,-Av9d ASFLAGS-.os += -Wa,-Av9d ASFLAGS-.op += -Wa,-Av9d ASFLAGS-.oS += -Wa,-Av9d - -# nscd uses atomic_spin_nop which in turn requires cpu_relax -ifeq ($(subdir),nscd) -routines += cpu_relax -endif - -ifeq ($(subdir), nptl) -libpthread-routines += cpu_relax -endif diff --git a/sysdeps/sparc/sparc32/sparcv9/atomic-machine.h b/sysdeps/sparc/sparc32/sparcv9/atomic-machine.h deleted file mode 100644 index 8d64f0729a..0000000000 --- a/sysdeps/sparc/sparc32/sparcv9/atomic-machine.h +++ /dev/null @@ -1,108 +0,0 @@ -/* Atomic operations. sparcv9 version. - Copyright (C) 2003-2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek , 2003. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include - -typedef int8_t atomic8_t; -typedef uint8_t uatomic8_t; -typedef int_fast8_t atomic_fast8_t; -typedef uint_fast8_t uatomic_fast8_t; - -typedef int16_t atomic16_t; -typedef uint16_t uatomic16_t; -typedef int_fast16_t atomic_fast16_t; -typedef uint_fast16_t uatomic_fast16_t; - -typedef int32_t atomic32_t; -typedef uint32_t uatomic32_t; -typedef int_fast32_t atomic_fast32_t; -typedef uint_fast32_t uatomic_fast32_t; - -typedef int64_t atomic64_t; -typedef uint64_t uatomic64_t; -typedef int_fast64_t atomic_fast64_t; -typedef uint_fast64_t uatomic_fast64_t; - -typedef intptr_t atomicptr_t; -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 - -/* XXX Is this actually correct? */ -#define ATOMIC_EXCHANGE_USES_CAS 0 - - -#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \ - (abort (), (__typeof (*mem)) 0) - -#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \ - (abort (), (__typeof (*mem)) 0) - -#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \ -({ \ - __typeof (*(mem)) __acev_tmp; \ - __typeof (mem) __acev_mem = (mem); \ - if (__builtin_constant_p (oldval) && (oldval) == 0) \ - __asm __volatile ("cas [%3], %%g0, %0" \ - : "=r" (__acev_tmp), "=m" (*__acev_mem) \ - : "m" (*__acev_mem), "r" (__acev_mem), \ - "0" (newval) : "memory"); \ - else \ - __asm __volatile ("cas [%4], %2, %0" \ - : "=r" (__acev_tmp), "=m" (*__acev_mem) \ - : "r" (oldval), "m" (*__acev_mem), "r" (__acev_mem), \ - "0" (newval) : "memory"); \ - __acev_tmp; }) - -/* This can be implemented if needed. */ -#define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \ - (abort (), (__typeof (*mem)) 0) - -#define atomic_exchange_acq(mem, newvalue) \ - ({ __typeof (*(mem)) __oldval; \ - __typeof (mem) __memp = (mem); \ - __typeof (*(mem)) __value = (newvalue); \ - \ - if (sizeof (*(mem)) == 4) \ - __asm ("swap %0, %1" \ - : "=m" (*__memp), "=r" (__oldval) \ - : "m" (*__memp), "1" (__value) : "memory"); \ - else \ - abort (); \ - __oldval; }) - -#define atomic_compare_and_exchange_val_24_acq(mem, newval, oldval) \ - atomic_compare_and_exchange_val_acq (mem, newval, oldval) - -#define atomic_exchange_24_rel(mem, newval) \ - atomic_exchange_rel (mem, newval) - -#define atomic_full_barrier() \ - __asm __volatile ("membar #LoadLoad | #LoadStore" \ - " | #StoreLoad | #StoreStore" : : : "memory") -#define atomic_read_barrier() \ - __asm __volatile ("membar #LoadLoad | #LoadStore" : : : "memory") -#define atomic_write_barrier() \ - __asm __volatile ("membar #LoadStore | #StoreStore" : : : "memory") - -extern void __cpu_relax (void); -#define atomic_spin_nop() __cpu_relax () diff --git a/sysdeps/sparc/sparc32/sparcv9/cpu_relax.c b/sysdeps/sparc/sparc32/sparcv9/cpu_relax.c deleted file mode 100644 index 1670cf6558..0000000000 --- a/sysdeps/sparc/sparc32/sparcv9/cpu_relax.c +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/sysdeps/sparc/sparc64/Makefile b/sysdeps/sparc/sparc64/Makefile index 7ed4c357bc..7e3b62a595 100644 --- a/sysdeps/sparc/sparc64/Makefile +++ b/sysdeps/sparc/sparc64/Makefile @@ -29,15 +29,6 @@ ASFLAGS-.os += -Wa,-Av9d ASFLAGS-.op += -Wa,-Av9d ASFLAGS-.oS += -Wa,-Av9d -# nscd uses atomic_spin_nop which in turn requires cpu_relax -ifeq ($(subdir),nscd) -routines += cpu_relax -endif - -ifeq ($(subdir),nptl) -libpthread-routines += cpu_relax -endif - ifeq ($(subdir),soft-fp) sparc64-quad-routines := qp_add qp_cmp qp_cmpe qp_div qp_dtoq qp_feq qp_fge \ qp_fgt qp_fle qp_flt qp_fne qp_itoq qp_mul qp_neg qp_qtod qp_qtoi \ diff --git a/sysdeps/sparc/sparc64/atomic-machine.h b/sysdeps/sparc/sparc64/atomic-machine.h deleted file mode 100644 index 4e1fc04eca..0000000000 --- a/sysdeps/sparc/sparc64/atomic-machine.h +++ /dev/null @@ -1,129 +0,0 @@ -/* Atomic operations. sparc64 version. - Copyright (C) 2003-2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek , 2003. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include - -typedef int8_t atomic8_t; -typedef uint8_t uatomic8_t; -typedef int_fast8_t atomic_fast8_t; -typedef uint_fast8_t uatomic_fast8_t; - -typedef int16_t atomic16_t; -typedef uint16_t uatomic16_t; -typedef int_fast16_t atomic_fast16_t; -typedef uint_fast16_t uatomic_fast16_t; - -typedef int32_t atomic32_t; -typedef uint32_t uatomic32_t; -typedef int_fast32_t atomic_fast32_t; -typedef uint_fast32_t uatomic_fast32_t; - -typedef int64_t atomic64_t; -typedef uint64_t uatomic64_t; -typedef int_fast64_t atomic_fast64_t; -typedef uint_fast64_t uatomic_fast64_t; - -typedef intptr_t atomicptr_t; -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 - -/* XXX Is this actually correct? */ -#define ATOMIC_EXCHANGE_USES_CAS 1 - - -#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \ - (abort (), (__typeof (*mem)) 0) - -#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \ - (abort (), (__typeof (*mem)) 0) - -#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \ -({ \ - __typeof (*(mem)) __acev_tmp; \ - __typeof (mem) __acev_mem = (mem); \ - if (__builtin_constant_p (oldval) && (oldval) == 0) \ - __asm __volatile ("cas [%3], %%g0, %0" \ - : "=r" (__acev_tmp), "=m" (*__acev_mem) \ - : "m" (*__acev_mem), "r" (__acev_mem), \ - "0" (newval) : "memory"); \ - else \ - __asm __volatile ("cas [%4], %2, %0" \ - : "=r" (__acev_tmp), "=m" (*__acev_mem) \ - : "r" (oldval), "m" (*__acev_mem), "r" (__acev_mem), \ - "0" (newval) : "memory"); \ - __acev_tmp; }) - -#define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \ -({ \ - __typeof (*(mem)) __acev_tmp; \ - __typeof (mem) __acev_mem = (mem); \ - if (__builtin_constant_p (oldval) && (oldval) == 0) \ - __asm __volatile ("casx [%3], %%g0, %0" \ - : "=r" (__acev_tmp), "=m" (*__acev_mem) \ - : "m" (*__acev_mem), "r" (__acev_mem), \ - "0" ((long) (newval)) : "memory"); \ - else \ - __asm __volatile ("casx [%4], %2, %0" \ - : "=r" (__acev_tmp), "=m" (*__acev_mem) \ - : "r" ((long) (oldval)), "m" (*__acev_mem), \ - "r" (__acev_mem), "0" ((long) (newval)) : "memory"); \ - __acev_tmp; }) - -#define atomic_exchange_acq(mem, newvalue) \ - ({ __typeof (*(mem)) __oldval, __val; \ - __typeof (mem) __memp = (mem); \ - __typeof (*(mem)) __value = (newvalue); \ - \ - if (sizeof (*(mem)) == 4) \ - __asm ("swap %0, %1" \ - : "=m" (*__memp), "=r" (__oldval) \ - : "m" (*__memp), "1" (__value) : "memory"); \ - else \ - { \ - __val = *__memp; \ - do \ - { \ - __oldval = __val; \ - __val = atomic_compare_and_exchange_val_acq (__memp, __value, \ - __oldval); \ - } \ - while (__builtin_expect (__val != __oldval, 0)); \ - } \ - __oldval; }) - -#define atomic_compare_and_exchange_val_24_acq(mem, newval, oldval) \ - atomic_compare_and_exchange_val_acq (mem, newval, oldval) - -#define atomic_exchange_24_rel(mem, newval) \ - atomic_exchange_rel (mem, newval) - -#define atomic_full_barrier() \ - __asm __volatile ("membar #LoadLoad | #LoadStore" \ - " | #StoreLoad | #StoreStore" : : : "memory") -#define atomic_read_barrier() \ - __asm __volatile ("membar #LoadLoad | #LoadStore" : : : "memory") -#define atomic_write_barrier() \ - __asm __volatile ("membar #LoadStore | #StoreStore" : : : "memory") - -extern void __cpu_relax (void); -#define atomic_spin_nop() __cpu_relax () diff --git a/sysdeps/unix/sysv/linux/sparc/lowlevellock.h b/sysdeps/unix/sysv/linux/sparc/lowlevellock.h deleted file mode 100644 index 6c005e8ffa..0000000000 --- a/sysdeps/unix/sysv/linux/sparc/lowlevellock.h +++ /dev/null @@ -1,130 +0,0 @@ -/* Copyright (C) 2003-2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek , 2003. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifndef _LOWLEVELLOCK_H -#define _LOWLEVELLOCK_H 1 - -#include -#include -#include -#include -#include -#include - -#include - -static inline int -__attribute__ ((always_inline)) -__lll_trylock (int *futex) -{ - return atomic_compare_and_exchange_val_24_acq (futex, 1, 0) != 0; -} -#define lll_trylock(futex) __lll_trylock (&(futex)) - -static inline int -__attribute__ ((always_inline)) -__lll_cond_trylock (int *futex) -{ - return atomic_compare_and_exchange_val_24_acq (futex, 2, 0) != 0; -} -#define lll_cond_trylock(futex) __lll_cond_trylock (&(futex)) - - -extern void __lll_lock_wait_private (int *futex) attribute_hidden; -extern void __lll_lock_wait (int *futex, int private) attribute_hidden; - -static inline void -__attribute__ ((always_inline)) -__lll_lock (int *futex, int private) -{ - int val = atomic_compare_and_exchange_val_24_acq (futex, 1, 0); - - if (__glibc_unlikely (val != 0)) - { - if (__builtin_constant_p (private) && private == LLL_PRIVATE) - __lll_lock_wait_private (futex); - else - __lll_lock_wait (futex, private); - } -} -#define lll_lock(futex, private) __lll_lock (&(futex), private) - -static inline void -__attribute__ ((always_inline)) -__lll_cond_lock (int *futex, int private) -{ - int val = atomic_compare_and_exchange_val_24_acq (futex, 2, 0); - - if (__glibc_unlikely (val != 0)) - __lll_lock_wait (futex, private); -} -#define lll_cond_lock(futex, private) __lll_cond_lock (&(futex), private) - - -extern int __lll_clocklock_wait (int *futex, clockid_t, int val, - const struct timespec *, - int private) attribute_hidden; - -#define lll_timedwait(futex, val, clockid, abstime, private) \ - __lll_clocklock_wait (futex, val, clockid, abstime, private) - -static inline int -__attribute__ ((always_inline)) -__lll_clocklock (int *futex, clockid_t clockid, - const struct timespec *abstime, int private) -{ - int val = atomic_compare_and_exchange_val_24_acq (futex, 1, 0); - int result = 0; - - if (__glibc_unlikely (val != 0)) - { - do - { - int oldval = atomic_compare_and_exchange_val_24_acq (futex, val, 1); - if (oldval != 0) - { - result = __lll_clocklock_wait (futex, 2, clockid, abstime, - private); - if (result == EINVAL || result == ETIMEDOUT) - break; - } - } - while (atomic_compare_and_exchange_val_24_acq (futex, val, 0) != 0); - } - return result; -} -#define lll_clocklock(futex, clockid, abstime, private) \ - __lll_clocklock (&(futex), clockid, abstime, private) - -#define lll_unlock(lock, private) \ - ((void) ({ \ - int *__futex = &(lock); \ - int __private = (private); \ - int __val = atomic_exchange_24_rel (__futex, 0); \ - if (__glibc_unlikely (__val > 1)) \ - lll_futex_wake (__futex, 1, __private); \ - })) - -#define lll_islocked(futex) \ - (futex != 0) - -/* Initializers for lock. */ -#define LLL_LOCK_INITIALIZER (0) -#define LLL_LOCK_INITIALIZER_LOCKED (1) - -#endif /* lowlevellock.h */