Message ID | 20230207001618.458947-20-christoph.muellner@vrull.eu |
---|---|
State | New |
Headers | show |
Series | riscv: ifunc support with optimized mem*/str*/cpu_relax routines | expand |
Note that all implementations must support `pause`, since it's a HINT instruction encoded within a base-ISA instruction that has no architecturally visible effect. So it's not clear to me that there's any virtue in distinguishing implementations that claim to support Zihintpause from those that don't. On Mon, Feb 6, 2023 at 4:17 PM Christoph Muellner <christoph.muellner@vrull.eu> wrote: > > From: Christoph Müllner <christoph.muellner@vrull.eu> > > The spinning loop of PTHREAD_MUTEX_ADAPTIVE_NP provides the hook > atomic_spin_nop() that can be used by architectures. > > On RISC-V we have two instructions that can be used here: > * WRS.STO from the Zawrs extension > * PAUSE from the Zihintpause extension > > Let's use these instructions and prefer WRS.STO over PAUSE > (based on availability of the corresponding ISA extension > at runtime). > > Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu> > --- > sysdeps/riscv/multiarch/Makefile | 5 +++ > sysdeps/riscv/multiarch/cpu_relax.c | 36 +++++++++++++++++ > sysdeps/riscv/multiarch/cpu_relax_impl.S | 40 +++++++++++++++++++ > .../unix/sysv/linux/riscv/atomic-machine.h | 3 ++ > 4 files changed, 84 insertions(+) > create mode 100644 sysdeps/riscv/multiarch/cpu_relax.c > create mode 100644 sysdeps/riscv/multiarch/cpu_relax_impl.S > > diff --git a/sysdeps/riscv/multiarch/Makefile b/sysdeps/riscv/multiarch/Makefile > index 9f22e31b99..b5b9fcf986 100644 > --- a/sysdeps/riscv/multiarch/Makefile > +++ b/sysdeps/riscv/multiarch/Makefile > @@ -17,3 +17,8 @@ sysdep_routines += \ > strncmp_generic \ > strncmp_zbb > endif > + > +# nscd uses atomic_spin_nop which in turn requires cpu_relax > +ifeq ($(subdir),nscd) > +routines += cpu_relax cpu_relax_impl > +endif > diff --git a/sysdeps/riscv/multiarch/cpu_relax.c b/sysdeps/riscv/multiarch/cpu_relax.c > new file mode 100644 > index 0000000000..4e6825ca50 > --- /dev/null > +++ b/sysdeps/riscv/multiarch/cpu_relax.c > @@ -0,0 +1,36 @@ > +/* CPU strand yielding for busy loops. RISC-V version. > + Copyright (C) 2022 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 > + <https://www.gnu.org/licenses/>. */ > + > +#include <ldsodefs.h> > +#include <init-arch.h> > + > +void __cpu_relax (void); > +extern void __cpu_relax_zawrs (void); > +extern void __cpu_relax_zihintpause (void); > + > +static void > +__cpu_relax_generic (void) > +{ > +} > + > +libc_ifunc (__cpu_relax, > + HAVE_RV(zawrs) > + ? __cpu_relax_zawrs > + : HAVE_RV(zihintpause) > + ? __cpu_relax_zihintpause > + : __cpu_relax_generic); > diff --git a/sysdeps/riscv/multiarch/cpu_relax_impl.S b/sysdeps/riscv/multiarch/cpu_relax_impl.S > new file mode 100644 > index 0000000000..5d349c351f > --- /dev/null > +++ b/sysdeps/riscv/multiarch/cpu_relax_impl.S > @@ -0,0 +1,40 @@ > +/* Copyright (C) 2022 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 > + <https://www.gnu.org/licenses/>. */ > + > +#include <sysdep.h> > +#include <sys/asm.h> > + > +.option push > +.option arch,+zawrs > + > +ENTRY_ALIGN (__cpu_relax_zawrs, 4) > + wrs.sto > + ret > +END (__cpu_relax_zawrs) > + > +.option pop > + > +.option push > +.option arch,+zihintpause > + > +ENTRY_ALIGN (__cpu_relax_zihintpause, 4) > + pause > + ret > +END (__cpu_relax_zihintpause) > + > +.option pop > diff --git a/sysdeps/unix/sysv/linux/riscv/atomic-machine.h b/sysdeps/unix/sysv/linux/riscv/atomic-machine.h > index dbf70d8d57..88aa58ef95 100644 > --- a/sysdeps/unix/sysv/linux/riscv/atomic-machine.h > +++ b/sysdeps/unix/sysv/linux/riscv/atomic-machine.h > @@ -178,4 +178,7 @@ > # error "ISAs that do not subsume the A extension are not supported" > #endif /* !__riscv_atomic */ > > +extern void __cpu_relax (void); > +#define atomic_spin_nop() __cpu_relax() > + > #endif /* bits/atomic.h */ > -- > 2.39.1 >
On Tue, Feb 7, 2023 at 1:23 AM Andrew Waterman <andrew@sifive.com> wrote: > Note that all implementations must support `pause`, since it's a HINT > instruction encoded within a base-ISA instruction that has no > architecturally visible effect. So it's not clear to me that there's > any virtue in distinguishing implementations that claim to support > Zihintpause from those that don't. > Will be considered in a v2. Thanks! > > > On Mon, Feb 6, 2023 at 4:17 PM Christoph Muellner > <christoph.muellner@vrull.eu> wrote: > > > > From: Christoph Müllner <christoph.muellner@vrull.eu> > > > > The spinning loop of PTHREAD_MUTEX_ADAPTIVE_NP provides the hook > > atomic_spin_nop() that can be used by architectures. > > > > On RISC-V we have two instructions that can be used here: > > * WRS.STO from the Zawrs extension > > * PAUSE from the Zihintpause extension > > > > Let's use these instructions and prefer WRS.STO over PAUSE > > (based on availability of the corresponding ISA extension > > at runtime). > > > > Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu> > > --- > > sysdeps/riscv/multiarch/Makefile | 5 +++ > > sysdeps/riscv/multiarch/cpu_relax.c | 36 +++++++++++++++++ > > sysdeps/riscv/multiarch/cpu_relax_impl.S | 40 +++++++++++++++++++ > > .../unix/sysv/linux/riscv/atomic-machine.h | 3 ++ > > 4 files changed, 84 insertions(+) > > create mode 100644 sysdeps/riscv/multiarch/cpu_relax.c > > create mode 100644 sysdeps/riscv/multiarch/cpu_relax_impl.S > > > > diff --git a/sysdeps/riscv/multiarch/Makefile > b/sysdeps/riscv/multiarch/Makefile > > index 9f22e31b99..b5b9fcf986 100644 > > --- a/sysdeps/riscv/multiarch/Makefile > > +++ b/sysdeps/riscv/multiarch/Makefile > > @@ -17,3 +17,8 @@ sysdep_routines += \ > > strncmp_generic \ > > strncmp_zbb > > endif > > + > > +# nscd uses atomic_spin_nop which in turn requires cpu_relax > > +ifeq ($(subdir),nscd) > > +routines += cpu_relax cpu_relax_impl > > +endif > > diff --git a/sysdeps/riscv/multiarch/cpu_relax.c > b/sysdeps/riscv/multiarch/cpu_relax.c > > new file mode 100644 > > index 0000000000..4e6825ca50 > > --- /dev/null > > +++ b/sysdeps/riscv/multiarch/cpu_relax.c > > @@ -0,0 +1,36 @@ > > +/* CPU strand yielding for busy loops. RISC-V version. > > + Copyright (C) 2022 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 > > + <https://www.gnu.org/licenses/>. */ > > + > > +#include <ldsodefs.h> > > +#include <init-arch.h> > > + > > +void __cpu_relax (void); > > +extern void __cpu_relax_zawrs (void); > > +extern void __cpu_relax_zihintpause (void); > > + > > +static void > > +__cpu_relax_generic (void) > > +{ > > +} > > + > > +libc_ifunc (__cpu_relax, > > + HAVE_RV(zawrs) > > + ? __cpu_relax_zawrs > > + : HAVE_RV(zihintpause) > > + ? __cpu_relax_zihintpause > > + : __cpu_relax_generic); > > diff --git a/sysdeps/riscv/multiarch/cpu_relax_impl.S > b/sysdeps/riscv/multiarch/cpu_relax_impl.S > > new file mode 100644 > > index 0000000000..5d349c351f > > --- /dev/null > > +++ b/sysdeps/riscv/multiarch/cpu_relax_impl.S > > @@ -0,0 +1,40 @@ > > +/* Copyright (C) 2022 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 > > + <https://www.gnu.org/licenses/>. */ > > + > > +#include <sysdep.h> > > +#include <sys/asm.h> > > + > > +.option push > > +.option arch,+zawrs > > + > > +ENTRY_ALIGN (__cpu_relax_zawrs, 4) > > + wrs.sto > > + ret > > +END (__cpu_relax_zawrs) > > + > > +.option pop > > + > > +.option push > > +.option arch,+zihintpause > > + > > +ENTRY_ALIGN (__cpu_relax_zihintpause, 4) > > + pause > > + ret > > +END (__cpu_relax_zihintpause) > > + > > +.option pop > > diff --git a/sysdeps/unix/sysv/linux/riscv/atomic-machine.h > b/sysdeps/unix/sysv/linux/riscv/atomic-machine.h > > index dbf70d8d57..88aa58ef95 100644 > > --- a/sysdeps/unix/sysv/linux/riscv/atomic-machine.h > > +++ b/sysdeps/unix/sysv/linux/riscv/atomic-machine.h > > @@ -178,4 +178,7 @@ > > # error "ISAs that do not subsume the A extension are not supported" > > #endif /* !__riscv_atomic */ > > > > +extern void __cpu_relax (void); > > +#define atomic_spin_nop() __cpu_relax() > > + > > #endif /* bits/atomic.h */ > > -- > > 2.39.1 > > >
diff --git a/sysdeps/riscv/multiarch/Makefile b/sysdeps/riscv/multiarch/Makefile index 9f22e31b99..b5b9fcf986 100644 --- a/sysdeps/riscv/multiarch/Makefile +++ b/sysdeps/riscv/multiarch/Makefile @@ -17,3 +17,8 @@ sysdep_routines += \ strncmp_generic \ strncmp_zbb endif + +# nscd uses atomic_spin_nop which in turn requires cpu_relax +ifeq ($(subdir),nscd) +routines += cpu_relax cpu_relax_impl +endif diff --git a/sysdeps/riscv/multiarch/cpu_relax.c b/sysdeps/riscv/multiarch/cpu_relax.c new file mode 100644 index 0000000000..4e6825ca50 --- /dev/null +++ b/sysdeps/riscv/multiarch/cpu_relax.c @@ -0,0 +1,36 @@ +/* CPU strand yielding for busy loops. RISC-V version. + Copyright (C) 2022 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 + <https://www.gnu.org/licenses/>. */ + +#include <ldsodefs.h> +#include <init-arch.h> + +void __cpu_relax (void); +extern void __cpu_relax_zawrs (void); +extern void __cpu_relax_zihintpause (void); + +static void +__cpu_relax_generic (void) +{ +} + +libc_ifunc (__cpu_relax, + HAVE_RV(zawrs) + ? __cpu_relax_zawrs + : HAVE_RV(zihintpause) + ? __cpu_relax_zihintpause + : __cpu_relax_generic); diff --git a/sysdeps/riscv/multiarch/cpu_relax_impl.S b/sysdeps/riscv/multiarch/cpu_relax_impl.S new file mode 100644 index 0000000000..5d349c351f --- /dev/null +++ b/sysdeps/riscv/multiarch/cpu_relax_impl.S @@ -0,0 +1,40 @@ +/* Copyright (C) 2022 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 + <https://www.gnu.org/licenses/>. */ + +#include <sysdep.h> +#include <sys/asm.h> + +.option push +.option arch,+zawrs + +ENTRY_ALIGN (__cpu_relax_zawrs, 4) + wrs.sto + ret +END (__cpu_relax_zawrs) + +.option pop + +.option push +.option arch,+zihintpause + +ENTRY_ALIGN (__cpu_relax_zihintpause, 4) + pause + ret +END (__cpu_relax_zihintpause) + +.option pop diff --git a/sysdeps/unix/sysv/linux/riscv/atomic-machine.h b/sysdeps/unix/sysv/linux/riscv/atomic-machine.h index dbf70d8d57..88aa58ef95 100644 --- a/sysdeps/unix/sysv/linux/riscv/atomic-machine.h +++ b/sysdeps/unix/sysv/linux/riscv/atomic-machine.h @@ -178,4 +178,7 @@ # error "ISAs that do not subsume the A extension are not supported" #endif /* !__riscv_atomic */ +extern void __cpu_relax (void); +#define atomic_spin_nop() __cpu_relax() + #endif /* bits/atomic.h */