[PATCH v3 0/3] Add a futex interface to glibc (sys/futex.h)
Adhemerval Zanella
adhemerval.zanella@linaro.org
Tue Aug 25 16:50:23 GMT 2026
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.
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).
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.
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.
Adhemerval Zanella (3):
nptl: Add __ prefix to the futex-internal.h functions
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 | 36 ++-
nptl/lowlevellock.c | 4 +-
nptl/nptl_setxid.c | 12 +-
nptl/pthread_barrier_destroy.c | 2 +-
nptl/pthread_barrier_wait.c | 8 +-
nptl/pthread_clockjoin.c | 2 +-
nptl/pthread_cond_broadcast.c | 4 +-
nptl/pthread_cond_common.c | 4 +-
nptl/pthread_cond_destroy.c | 2 +-
nptl/pthread_cond_signal.c | 2 +-
nptl/pthread_cond_wait.c | 6 +-
nptl/pthread_create.c | 8 +-
nptl/pthread_join_common.c | 2 +-
nptl/pthread_mutex_init.c | 2 +-
nptl/pthread_mutex_lock.c | 6 +-
nptl/pthread_mutex_setprioceiling.c | 4 +-
nptl/pthread_mutex_timedlock.c | 4 +-
nptl/pthread_mutex_trylock.c | 2 +-
nptl/pthread_mutex_unlock.c | 6 +-
nptl/pthread_once.c | 6 +-
nptl/pthread_rwlock_common.c | 20 +-
nptl/pthread_rwlock_tryrdlock.c | 2 +-
nptl/sem_clockwait.c | 2 +-
nptl/sem_post.c | 6 +-
nptl/sem_waitcommon.c | 2 +-
sysdeps/nptl/aio_misc.h | 2 +-
sysdeps/nptl/dl-thread_gscope_wait.c | 4 +-
sysdeps/nptl/futex-internal.h | 78 ++++---
sysdeps/nptl/gai_misc.h | 2 +-
sysdeps/nptl/libc_start_call_main.h | 2 +-
sysdeps/nptl/lowlevellock-futex.h | 12 +
sysdeps/pthread/tst-rwlock-tryrdlock-stall.c | 2 +-
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 +
80 files changed, 1400 insertions(+), 101 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
--
2.53.0
More information about the Libc-alpha
mailing list