Re: [RFC PATCH 0/2] Add a futex interface to glibc (sys/futex.h)
Carlos O'Donell <[email protected]>
| Newsgroups | gmane.comp.lib.glibc.alpha |
|---|---|
| Organization | Red Hat, LLC. |
| Message-ID | <[email protected]> |
On 8/25/26 12:37 PM, Adhemerval Zanella wrote: > This patchset adds wrappers for the futex system call through a new > <sys/futex.h> header. They are futex_wait, futex_timedwait, > futex_wake, futex_requeue, and futex_waitv. I worked through a prototype for this last year after my LPC talk about creating wrappers for all syscalls. I think this is the right direction to go and I can review the wrappers. I think we should expose as much as is not deprecated. > Exporting a futex interface from libc is a long-standing request, as > the futex syscall is the blocking building block for essentially > every custom synchronization primitive on Linux. And since glibc > provides no wrapper, every project ends up hand-rolling it; with > per-architecture syscall assembly, ad-hoc time64 syscall selection, > and workarounds for the syscall's historical quirks duplicated in > each of them (libstdc++, libc++, libgomp, libitm, the Go runtime, > OpenMP, allocators, and so on). Right. > It has also become relevant as the kernel expands the futex interface, > where futex_waitv and the futex2 syscall family only make sense to > expose from libc if there is a consistent futex API to build on. Agreed. > This patchset provides that base operations plus futex_waitv, sharing > one set of conventions (flags following the kernel FUTEX_PRIVATE_FLAG, > absolute timeouts with an explicit clockid, -1/errno error reporting, > no cancellation points), so future futex2 additions are incremental > rather than a new design. > > Only the well-defined subset of the kernel interface is exposed (the > racy unchecked FUTEX_REQUEUE, the removed FUTEX_FD, FUTEX_WAKE_OP, > bitset matching, and the PI operations are left out). The > futex_timedwait supports both time_t sizes with the usual TIME_BITS=64 > redirection; futex_waitv mirrors the kernel ABI directly (struct layout, > argument order, FUTEX2* per-waiter flags) and is 64-bit time_t only. > The wrappers compile down to the same code as a hand-rolled syscall > (the waits and requeue are a flags check plus a tail call; wake > inlines the syscall), so there is no cost to adopting them. > > To verify the interface's usability, I built a proof of concept that > converts the two futex users in GCC (libitm and libgomp) to the new > functions. The required work is minimal: libitm's wrappers become > three-line calls, and libgomp only needs an asm-label binding because > its internal wrappers reuse the utex_wait/futex_wake names. > > In both cases the per-architecture syscall assembly and the obsolete > private-to-shared runtime fallbacks become unnecessary. A survey of > the remaining futex users in GCC and LLVM (libstdc++, libc++, libgo, > OpenMP, scudo) showed that all of their usage should map onto this > interface as well. Great! I'll wait for a full non-RFC to review. > Adhemerval Zanella (2): > linux: Add futex_wait, futex_timedwait, futex_wake, and futex_requeue > linux: Add futex_waitv > > NEWS | 9 +- > include/sys/futex.h | 32 +++ > manual/threads.texi | 211 ++++++++++++++++++ > nptl/futex-internal.c | 32 +++ > sysdeps/nptl/futex-internal.h | 58 +++-- > sysdeps/nptl/lowlevellock-futex.h | 12 + > sysdeps/unix/sysv/linux/Makefile | 20 ++ > sysdeps/unix/sysv/linux/Versions | 10 + > sysdeps/unix/sysv/linux/aarch64/libc.abilist | 5 + > sysdeps/unix/sysv/linux/alpha/libc.abilist | 5 + > sysdeps/unix/sysv/linux/arc/libc.abilist | 5 + > sysdeps/unix/sysv/linux/arm/be/libc.abilist | 6 + > sysdeps/unix/sysv/linux/arm/le/libc.abilist | 6 + > sysdeps/unix/sysv/linux/csky/libc.abilist | 6 + > sysdeps/unix/sysv/linux/futex_requeue.c | 35 +++ > sysdeps/unix/sysv/linux/futex_timedwait.c | 55 +++++ > sysdeps/unix/sysv/linux/futex_wait.c | 36 +++ > sysdeps/unix/sysv/linux/futex_waitv.c | 38 ++++ > sysdeps/unix/sysv/linux/futex_wake.c | 38 ++++ > sysdeps/unix/sysv/linux/hppa/libc.abilist | 6 + > sysdeps/unix/sysv/linux/i386/libc.abilist | 6 + > .../sysv/linux/loongarch/ilp32/libc.abilist | 5 + > .../sysv/linux/loongarch/lp64/libc.abilist | 5 + > .../sysv/linux/m68k/coldfire/libc.abilist | 6 + > .../unix/sysv/linux/m68k/m680x0/libc.abilist | 6 + > .../sysv/linux/microblaze/be/libc.abilist | 6 + > .../sysv/linux/microblaze/le/libc.abilist | 6 + > .../sysv/linux/mips/mips32/fpu/libc.abilist | 6 + > .../sysv/linux/mips/mips32/nofpu/libc.abilist | 6 + > .../sysv/linux/mips/mips64/n32/libc.abilist | 6 + > .../sysv/linux/mips/mips64/n64/libc.abilist | 5 + > sysdeps/unix/sysv/linux/or1k/libc.abilist | 5 + > .../linux/powerpc/powerpc32/fpu/libc.abilist | 6 + > .../powerpc/powerpc32/nofpu/libc.abilist | 6 + > .../linux/powerpc/powerpc64/be/libc.abilist | 5 + > .../linux/powerpc/powerpc64/le/libc.abilist | 5 + > .../unix/sysv/linux/riscv/rv32/libc.abilist | 5 + > .../unix/sysv/linux/riscv/rv64/libc.abilist | 5 + > sysdeps/unix/sysv/linux/s390/libc.abilist | 5 + > sysdeps/unix/sysv/linux/sh/be/libc.abilist | 6 + > sysdeps/unix/sysv/linux/sh/le/libc.abilist | 6 + > .../sysv/linux/sparc/sparc32/libc.abilist | 6 + > .../sysv/linux/sparc/sparc64/libc.abilist | 5 + > sysdeps/unix/sysv/linux/sys/futex.h | 135 +++++++++++ > sysdeps/unix/sysv/linux/tst-futex-consts.py | 71 ++++++ > sysdeps/unix/sysv/linux/tst-futex-time64.c | 1 + > .../unix/sysv/linux/tst-futex-waitv-time64.c | 1 + > sysdeps/unix/sysv/linux/tst-futex-waitv.c | 197 ++++++++++++++++ > sysdeps/unix/sysv/linux/tst-futex.c | 179 +++++++++++++++ > .../unix/sysv/linux/x86_64/64/libc.abilist | 5 + > .../unix/sysv/linux/x86_64/x32/libc.abilist | 5 + > 51 files changed, 1323 insertions(+), 24 deletions(-) > create mode 100644 include/sys/futex.h > create mode 100644 sysdeps/unix/sysv/linux/futex_requeue.c > create mode 100644 sysdeps/unix/sysv/linux/futex_timedwait.c > create mode 100644 sysdeps/unix/sysv/linux/futex_wait.c > create mode 100644 sysdeps/unix/sysv/linux/futex_waitv.c > create mode 100644 sysdeps/unix/sysv/linux/futex_wake.c > create mode 100644 sysdeps/unix/sysv/linux/sys/futex.h > create mode 100644 sysdeps/unix/sysv/linux/tst-futex-consts.py > create mode 100644 sysdeps/unix/sysv/linux/tst-futex-time64.c > create mode 100644 sysdeps/unix/sysv/linux/tst-futex-waitv-time64.c > create mode 100644 sysdeps/unix/sysv/linux/tst-futex-waitv.c > create mode 100644 sysdeps/unix/sysv/linux/tst-futex.c > -- Cheers, Carlos.