From patchwork Thu Aug 19 04:02:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Hua X-Patchwork-Id: 44704 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 706E6389704F for ; Thu, 19 Aug 2021 04:03:08 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 706E6389704F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1629345788; bh=ogDvjhDt+4tMUmNBMgE87Am0K+NEOIVfhb074zplkJ0=; h=Date:Subject:To:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=A6E2IAUuNdV19IpsfX/vVFGt+PXO9bE1UqRcFBsvGizooeU3ZwTEN9PgG/lQqAVQm Iox2diEC3eenUR+jsj47jI9T6D2YeX/QpW5axRB/9rN+d5QUiNxlSqRFgdgBHcMUnJ 0conoYidSKZGT3UPYlR3rVD53k9Nci2R13K3U/wk= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-yb1-xb29.google.com (mail-yb1-xb29.google.com [IPv6:2607:f8b0:4864:20::b29]) by sourceware.org (Postfix) with ESMTPS id DAA083861830 for ; Thu, 19 Aug 2021 04:02:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org DAA083861830 Received: by mail-yb1-xb29.google.com with SMTP id m193so9684557ybf.9 for ; Wed, 18 Aug 2021 21:02:37 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to:cc; bh=ogDvjhDt+4tMUmNBMgE87Am0K+NEOIVfhb074zplkJ0=; b=LmhsEfkazg4IkoeIE9/5UE4au/YWVSo+3sTNuwQRROqjGJwuQ9rMXB7x48OqbKaHbo cIK+33hXmi1vRBm9GiDwCltft4TPnw9JgXdQdeNRmSrhI5F2rrN5PQjHi5py83QbTZIb fTStFGjTrl6N1qDqDSiczSiRWC+aNHBa2/yqQC1i6aJhWfwdToQjDQNNb75vEiIG5jgP yYMtNSEZtc0mhp8MHb1JJnnvWjgRpdwI1IBqG8H1GC4tP+ulJsc8ep2Q6O1oEAy1M+yS MDIHJmSTMePGEYPvPscEsivzpFp9rCqeThv96mt1BBj8wRpqfOIBzjNAB5mpnrRDdiyF zS3A== X-Gm-Message-State: AOAM532tsPIEveZT42pE4byIwM7OQmsNCiLG9YWRCAt5VQZGkNdCK49p IKksvsPvo8DLAhQN0TLzcnI4ZF4omYn2uI7SLPKRU6Upcyn3JjV6 X-Google-Smtp-Source: ABdhPJzDpww82PyYRoQaZvoYTgC7ukuaGZhPD9wkoU+gCpMubnRyMsA3MXoNXer75MhEBQF4qMrM3+k5PT8K3C213tA= X-Received: by 2002:a25:af4a:: with SMTP id c10mr16229170ybj.482.1629345757345; Wed, 18 Aug 2021 21:02:37 -0700 (PDT) MIME-Version: 1.0 Date: Thu, 19 Aug 2021 12:02:25 +0800 Message-ID: Subject: [PATCH 5/14] [LoongArch] Atomic and Locking Routines To: libc-alpha@sourceware.org X-Spam-Status: No, score=-8.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Paul Hua via Libc-alpha From: Paul Hua Reply-To: Paul Hua Cc: Xu Chenghua , huangpei@loongson.cn, caiyinyu@loongson.cn Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" From 6962baf0d256997396a5492f2dd8162b85957e2d Mon Sep 17 00:00:00 2001 From: caiyinyu Date: Tue, 27 Jul 2021 15:47:07 +0800 Subject: [PATCH 05/14] LoongArch: Atomic and Locking Routines This patch implements various atomic and locking routines on LoongArch. * sysdeps/loongarch/nptl/bits/pthreadtypes-arch.h: New file. * sysdeps/loongarch/nptl/bits/semaphore.h: Likewise. * sysdeps/loongarch/nptl/libc-lowlevellock.c: Likewise. * sysdeps/unix/sysv/linux/loongarch/atomic-machine.h: Likewise. --- .../loongarch/nptl/bits/pthreadtypes-arch.h | 41 ++++ sysdeps/loongarch/nptl/bits/semaphore.h | 31 +++ sysdeps/loongarch/nptl/libc-lowlevellock.c | 8 + .../sysv/linux/loongarch/atomic-machine.h | 196 ++++++++++++++++++ 4 files changed, 276 insertions(+) create mode 100644 sysdeps/loongarch/nptl/bits/pthreadtypes-arch.h create mode 100644 sysdeps/loongarch/nptl/bits/semaphore.h create mode 100644 sysdeps/loongarch/nptl/libc-lowlevellock.c create mode 100644 sysdeps/unix/sysv/linux/loongarch/atomic-machine.h diff --git a/sysdeps/loongarch/nptl/bits/pthreadtypes-arch.h b/sysdeps/loongarch/nptl/bits/pthreadtypes-arch.h new file mode 100644 index 0000000000..221526d5fd --- /dev/null +++ b/sysdeps/loongarch/nptl/bits/pthreadtypes-arch.h @@ -0,0 +1,41 @@ +/* Machine-specific pthread type layouts. LoongArch version. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 _BITS_PTHREADTYPES_ARCH_H +#define _BITS_PTHREADTYPES_ARCH_H 1 + +#include + +#if _LOONGARCH_SIM == _ABILP64 +#define __SIZEOF_PTHREAD_ATTR_T 56 +#define __SIZEOF_PTHREAD_MUTEX_T 40 +#define __SIZEOF_PTHREAD_MUTEXATTR_T 4 +#define __SIZEOF_PTHREAD_COND_T 48 +#define __SIZEOF_PTHREAD_CONDATTR_T 4 +#define __SIZEOF_PTHREAD_RWLOCK_T 56 +#define __SIZEOF_PTHREAD_RWLOCKATTR_T 8 +#define __SIZEOF_PTHREAD_BARRIER_T 32 +#define __SIZEOF_PTHREAD_BARRIERATTR_T 4 +#else +#error "32bit LoongArch systems are not supported" +#endif + +#define __LOCK_ALIGNMENT +#define __ONCE_ALIGNMENT + +#endif /* bits/pthreadtypes.h */ diff --git a/sysdeps/loongarch/nptl/bits/semaphore.h b/sysdeps/loongarch/nptl/bits/semaphore.h new file mode 100644 index 0000000000..5b70e06324 --- /dev/null +++ b/sysdeps/loongarch/nptl/bits/semaphore.h @@ -0,0 +1,31 @@ +/* Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 _SEMAPHORE_H +#error "Never use directly; include instead." +#endif + +#define __SIZEOF_SEM_T (4 * __SIZEOF_POINTER__) + +/* Value returned if `sem_open' failed. */ +#define SEM_FAILED ((sem_t *) 0) + +typedef union +{ + char __size[__SIZEOF_SEM_T]; + long int __align; +} sem_t; diff --git a/sysdeps/loongarch/nptl/libc-lowlevellock.c b/sysdeps/loongarch/nptl/libc-lowlevellock.c new file mode 100644 index 0000000000..f4b8b5c193 --- /dev/null +++ b/sysdeps/loongarch/nptl/libc-lowlevellock.c @@ -0,0 +1,8 @@ +/* This kludge works around a libpthread static linking problem: + https://sourceware.org/bugzilla/show_bug.cgi?id=15648. */ + +#ifndef SHARED +#define __lll_lock_wait_private weak_function __lll_lock_wait_private +#endif + +#include diff --git a/sysdeps/unix/sysv/linux/loongarch/atomic-machine.h b/sysdeps/unix/sysv/linux/loongarch/atomic-machine.h new file mode 100644 index 0000000000..0304e1469b --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/atomic-machine.h @@ -0,0 +1,196 @@ +/* Atomic operations. LoongArch version. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 _LINUX_LOONGARCH_BITS_ATOMIC_H +#define _LINUX_LOONGARCH_BITS_ATOMIC_H 1 + +#include + +typedef int32_t atomic32_t; +typedef uint32_t uatomic32_t; + +typedef int64_t atomic64_t; +typedef uint64_t uatomic64_t; + +typedef intptr_t atomicptr_t; +typedef uintptr_t uatomicptr_t; +typedef intmax_t atomic_max_t; +typedef uintmax_t uatomic_max_t; + +#define atomic_full_barrier() __sync_synchronize () + +#ifdef __LP64__ +#define __HAVE_64B_ATOMICS 1 +#endif +#define USE_ATOMIC_COMPILER_BUILTINS 1 +#define ATOMIC_EXCHANGE_USES_CAS 0 + +/* Compare and exchange. + For all "bool" routines, we return FALSE if exchange succesful. */ + +#define __arch_compare_and_exchange_bool_8_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, model, \ + __ATOMIC_RELAXED); \ + }) + +#define __arch_compare_and_exchange_bool_16_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, model, \ + __ATOMIC_RELAXED); \ + }) + +#define __arch_compare_and_exchange_bool_32_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, model, \ + __ATOMIC_RELAXED); \ + }) + +#define __arch_compare_and_exchange_bool_64_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, model, \ + __ATOMIC_RELAXED); \ + }) + +#define __arch_compare_and_exchange_val_8_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, model, \ + __ATOMIC_RELAXED); \ + __oldval; \ + }) + +#define __arch_compare_and_exchange_val_16_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, model, \ + __ATOMIC_RELAXED); \ + __oldval; \ + }) + +#define __arch_compare_and_exchange_val_32_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, model, \ + __ATOMIC_RELAXED); \ + __oldval; \ + }) + +#define __arch_compare_and_exchange_val_64_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, model, \ + __ATOMIC_RELAXED); \ + __oldval; \ + }) + +/* Atomic compare and exchange. */ + +#define atomic_compare_and_exchange_bool_acq(mem, new, old) \ + __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, mem, new, old, \ + __ATOMIC_ACQUIRE) + +#define atomic_compare_and_exchange_val_acq(mem, new, old) \ + __atomic_val_bysize (__arch_compare_and_exchange_val, int, mem, new, old, \ + __ATOMIC_ACQUIRE) + +#define atomic_compare_and_exchange_val_rel(mem, new, old) \ + __atomic_val_bysize (__arch_compare_and_exchange_val, int, mem, new, old, \ + __ATOMIC_RELEASE) + +/* Atomic exchange (without compare). */ + +#define __arch_exchange_8_int(mem, newval, model) \ + __atomic_exchange_n (mem, newval, model) + +#define __arch_exchange_16_int(mem, newval, model) \ + __atomic_exchange_n (mem, newval, model) + +#define __arch_exchange_32_int(mem, newval, model) \ + __atomic_exchange_n (mem, newval, model) + +#define __arch_exchange_64_int(mem, newval, model) \ + __atomic_exchange_n (mem, newval, model) + +#define atomic_exchange_acq(mem, value) \ + __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_ACQUIRE) + +#define atomic_exchange_rel(mem, value) \ + __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_RELEASE) + +/* Atomically add value and return the previous (unincremented) value. */ + +#define __arch_exchange_and_add_8_int(mem, value, model) \ + __atomic_fetch_add (mem, value, model) + +#define __arch_exchange_and_add_16_int(mem, value, model) \ + __atomic_fetch_add (mem, value, model) + +#define __arch_exchange_and_add_32_int(mem, value, model) \ + __atomic_fetch_add (mem, value, model) + +#define __arch_exchange_and_add_64_int(mem, value, model) \ + __atomic_fetch_add (mem, value, model) + +#define atomic_exchange_and_add_acq(mem, value) \ + __atomic_val_bysize (__arch_exchange_and_add, int, mem, value, \ + __ATOMIC_ACQUIRE) + +#define atomic_exchange_and_add_rel(mem, value) \ + __atomic_val_bysize (__arch_exchange_and_add, int, mem, value, \ + __ATOMIC_RELEASE) + +/* Miscellaneous. */ + +#define asm_amo(which, mem, value) \ + ({ \ + __atomic_check_size (mem); \ + typeof (*mem) __tmp; \ + if (sizeof (__tmp) == 4) \ + asm volatile(which ".w" \ + "\t%0, %z2, %1" \ + : "=&r"(__tmp), "+ZB"(*(mem)) \ + : "rJ"(value)); \ + else if (sizeof (__tmp) == 8) \ + asm volatile(which ".d" \ + "\t%0, %z2, %1" \ + : "=&r"(__tmp), "+ZB"(*(mem)) \ + : "rJ"(value)); \ + else \ + abort (); \ + __tmp; \ + }) + +#define atomic_max(mem, value) asm_amo ("ammax_db", mem, value) +#define atomic_min(mem, value) asm_amo ("ammin_db", mem, value) + +#define atomic_bit_test_set(mem, bit) \ + ({ \ + typeof (*mem) __mask = (typeof (*mem)) 1 << (bit); \ + asm_amo ("amor_db", mem, __mask) & __mask; \ + }) + +#define catomic_exchange_and_add(mem, value) \ + atomic_exchange_and_add (mem, value) +#define catomic_max(mem, value) atomic_max (mem, value) + +#endif /* bits/atomic.h */