| Message ID | 20260814183612.1780736-1-andrealmeid@igalia.com (mailing list archive) |
|---|---|
| Headers |
Return-Path: <libc-alpha-bounces~patchwork=sourceware.org@sourceware.org> X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3719E4BA9011 for <patchwork@sourceware.org>; Fri, 14 Aug 2026 18:37:47 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3719E4BA9011 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=igalia.com header.i=@igalia.com header.a=rsa-sha256 header.s=20170329 header.b=qaW/s/Qa X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from fanzine2.igalia.com (fanzine2.igalia.com [213.97.179.56]) by sourceware.org (Postfix) with ESMTPS id 9966C4BA5434 for <libc-alpha@sourceware.org>; Fri, 14 Aug 2026 18:36:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9966C4BA5434 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=igalia.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=igalia.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 9966C4BA5434 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=213.97.179.56 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1786732612; cv=none; b=OJJBHKxdIrZDI5b8QkfnMzQA3nOiXvr20tsFdcXkogYG9VHCSCuI0c7+7i8Ol7cmO8hc8H0cuf31S9P424x6qfgCmnGMD/IYeHkB8DQC7+2y8NqOBRTOK0lyU+jlcn+ZrMCDNvhExGAhx+Nf41FlfBW0wHhejqVjziBQZZWEBc4= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1786732612; c=relaxed/simple; bh=IGj+CaZEodashnR8omhACLstlsoIw/b3jsj3ufJfI58=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=nRtIO4o+ZTS2TOABReQXpSiIcPKWHeAMQ3qJWZ1HhY6XWyXuSyP10nkGdj1lKx2nkc7bUzzU08dmk4BUjlUof9dv5BZIpTDmjTOVSGOHWliIL3zAPfizO+wEkyl/+Zo7HpAx3H/gXUCCECHXKfPRVExYfnMp2V1XwPBRCBhg4Rs= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=igalia.com header.i=@igalia.com header.a=rsa-sha256 header.s=20170329 header.b=qaW/s/Qa DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9966C4BA5434 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:Content-Type:MIME-Version:Message-ID: Date:Subject:Cc:To:From:From:Reply-To; bh=54xtLpIwKpAFV1yT7UXISRi0QCyt+vefRBJ2IkhXYy4=; b=qaW/s/QaFe+N2cHzP85Jv2pidX vBzmmJ7Bw04q+EpnUneiq2Kj2wGYsBTQtypooLC4cuIn1wNFHPrwgWeoKdhTpkVx+zOwbOxJjd1md QaaLTZ/PfkSLFlUlljFk0eSDK5hAdvsz57rYu6oV3zo3p9OtI/xoFIaouHGZOBDv3DsNPG54jYGFf uZ2O6Q1omr5bTekxCSP9paVxtsq5vbwBdcsrs7Q0NnqDKZUcKACgH0LwvX/ZemJY8Ao1ksScJ/IW3 43Fofad+jv5aNAGMiKlKsF3t28d9nAeRmSfkXC5D7Ukmgbur9o7cn2SjSFoJm/wdYrAlCbJLijGs2 zBovxrgg==; Received: from [177.139.22.20] (helo=computador) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1wuwls-001xOF-GD; Fri, 14 Aug 2026 20:36:48 +0200 From: =?utf-8?q?Andr=C3=A9_Almeida?= <andrealmeid@igalia.com> To: libc-alpha@sourceware.org, carlos@redhat.com, adhemerval.zanella@linaro.org Cc: =?utf-8?q?Andr=C3=A9_Almeida?= <andrealmeid@igalia.com> Subject: [RFC PATCH 0/2] Linux: Add futex_waitv syscall wrapper Date: Fri, 14 Aug 2026 15:36:10 -0300 Message-ID: <20260814183612.1780736-1-andrealmeid@igalia.com> X-Mailer: git-send-email 2.55.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-3.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, KAM_SHORT, RCVD_IN_PBL, SPF_HELO_NONE, SPF_PASS, TXREP shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list <libc-alpha.sourceware.org> List-Unsubscribe: <https://sourceware.org/mailman/options/libc-alpha>, <mailto:libc-alpha-request@sourceware.org?subject=unsubscribe> List-Archive: <https://sourceware.org/pipermail/libc-alpha/> List-Post: <mailto:libc-alpha@sourceware.org> List-Help: <mailto:libc-alpha-request@sourceware.org?subject=help> List-Subscribe: <https://sourceware.org/mailman/listinfo/libc-alpha>, <mailto:libc-alpha-request@sourceware.org?subject=subscribe> Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org |
| Series |
Linux: Add futex_waitv syscall wrapper
|
|
Message
André Almeida
Aug. 14, 2026, 6:36 p.m. UTC
Hi folks, Based on a talk on last LPC by Carlos O'Donell[1], I'm sending this patch as a starting point to add the futex_waitv() syscall wrapper. I tried to base myself on the work done for others wrappers, but I see that there are missing details in my implementation, so I'm seeking guidance on how to approach this. Thanks! André [1] https://lpc.events/event/19/contributions/2220/ André Almeida (2): Linux: Add futex_waitv misc: tst-futex: Create futex test include/sys/futex.h | 4 ++ sysdeps/unix/sysv/linux/Makefile | 3 + sysdeps/unix/sysv/linux/futex_waitv.c | 32 +++++++++ sysdeps/unix/sysv/linux/sys/futex.h | 24 +++++++ sysdeps/unix/sysv/linux/tst-futex.c | 93 +++++++++++++++++++++++++++ 5 files changed, 156 insertions(+) create mode 100644 include/sys/futex.h create mode 100644 sysdeps/unix/sysv/linux/futex_waitv.c create mode 100644 sysdeps/unix/sysv/linux/sys/futex.h create mode 100644 sysdeps/unix/sysv/linux/tst-futex.c
Comments
On 14/08/26 15:36, André Almeida wrote: > Hi folks, > > Based on a talk on last LPC by Carlos O'Donell[1], I'm sending this patch as a > starting point to add the futex_waitv() syscall wrapper. > > I tried to base myself on the work done for others wrappers, but I see that > there are missing details in my implementation, so I'm seeking guidance on how > to approach this. > > Thanks! > André > > [1] https://lpc.events/event/19/contributions/2220/ This triggered two regressions from our CI [1]: FAIL: misc/check-installed-headers-c [...] :: sys/futex.h [...] :::: -D_XOPEN_SOURCE=700 In file included from ../sysdeps/unix/sysv/linux/sys/futex.h:6, from ../include/sys/futex.h:2, from /tmp/cih_test_lKjACY.c:10: ../include/struct___timespec64.h:5:23: error: ‘struct timespec’ declared inside parameter list will not be visible outside of this definition or declaration [-Werror] 5 | # define __timespec64 timespec | ^~~~~~~~ ../sysdeps/unix/sysv/linux/sys/futex.h:22:49: note: in expansion of macro ‘__timespec64’ 22 | unsigned int flags, const struct __timespec64 *timeout, [...] FAIL: misc/tst-futex original exit status 127 The check-installed-headers-c is a namespace pollution, which seems most likely from the bare '<struct___timespec64.h>' inclusion. The misc/tst-futex is most likely a build issue, since the patch does not export the futex_waitv from 'Versions', nor it updates the libc.abilist to check whether the symbols is correctly being exported. How did you test this? There were other issues, like missing Copyright headers and minor formatting issue. But I think the main issue is it feels incomplete and clunky to export a new futex interface where we still don't have a proper futex wrapper. In the testcase itself you had to use syscall to issue the FUTEX_WAKE. I think we should define and export a plain futex wrapper before adding this extension. I recall that one point of contention was that due the kABI futex ABI, a more extensible wrapper through varargs would be preferable than a one with pre-defined operations. However, our experience with varargs interfaces showed that it can be painful (like ioctl, prctl, etc); and futex operation are currently limited that I think we can set on a operation API. The main consumers of this possible futex interface are lock/condvar/synchronization implementers (C++ std::atomic::wait, language runtimes, Rust-style parking) who need async-signal-safety, and don't want errno clobbering or cancellation cleanup interacting with their own state machines. So I think we can start with something like: -- enum { FUTEX_FLAG_PRIVATE = 0, /* Default: process-private (fast path). */ FUTEX_FLAG_SHARED = 1 << 0, /* Cross-process, word in a shared mapping. */ }; int futex_wait (uint32_t *futexp, uint32_t expected, unsigned int flags); int futex_timedwait (uint32_t *futexp, uint32_t expected, clockid_t clockid, const struct timespec *abstime, unsigned int flags); int futex_wake (uint32_t *futexp, int count, unsigned int flags); int futex_requeue (uint32_t *futexp, uint32_t expected, int nwake, uint32_t *targetp, int nrequeue, unsigned int flags); -- * The function returns the error code, which maps to the INTERNAL_SYSCALL_CALL. Different than the pthread wrappers, EINTR is reported rather than auto-retried. * Timeouts are absolute-only, with an explicit clockid_t (restricted to CLOCK_MONOTONIC and CLOCK_REALTIME, NULL = infinite). This hides the worst kernel wart (which we handle on nptl/futex-internal.c): FUTEX_WAIT takes a relative CLOCK_MONOTONIC timeout while FUTEX_WAIT_BITSET takes an absolute one, and FUTEX_CLOCK_REALTIME composes inconsistently across ops. The implementation always uses FUTEX_WAIT_BITSET with FUTEX_BITSET_MATCH_ANY underneath, exactly like __futex_abstimed_wait64 does. * Since it is a new interface, support only for 64-bit time_t. * Explicitly excluded broken interfaces: FUTEX_FD, FUTEX_REQUEUE; * Not provided: - FUTEX_WAKE_OP: error-prone, and glibc itself abandoned its only use when the condvar was rewritten; - Bitset matching: exist in practice as a vehicle for absolute timeouts, which the API provides directly; - FUTEX_WAIT_REQUEUE_PI / FUTEX_CMP_REQUEUE_PI: subtle ordering requirements, and error-prone. - Robust futexes: single per-thread resource glibc already owns for PTHREAD_MUTEX_ROBUST; and exporting would possible create conflicts on *who* owns the list. * What I am not sure, but seems doable: - PI futexes (FUTEX_LOCK_PI/TRYLOCK_PI/UNLOCK_PI): the kernel dictates a lot of userland ABI (owner TID, FUTEX_WAITERS, FUTEX_OWNER_DIED), so exporting them means documenting that protocol as ABI. I will try to create POC so we can check if it makes sense. [1] https://patchwork.sourceware.org/project/glibc/patch/20260814183612.1780736-3-andrealmeid@igalia.com/ > > André Almeida (2): > Linux: Add futex_waitv > misc: tst-futex: Create futex test > > include/sys/futex.h | 4 ++ > sysdeps/unix/sysv/linux/Makefile | 3 + > sysdeps/unix/sysv/linux/futex_waitv.c | 32 +++++++++ > sysdeps/unix/sysv/linux/sys/futex.h | 24 +++++++ > sysdeps/unix/sysv/linux/tst-futex.c | 93 +++++++++++++++++++++++++++ > 5 files changed, 156 insertions(+) > create mode 100644 include/sys/futex.h > create mode 100644 sysdeps/unix/sysv/linux/futex_waitv.c > create mode 100644 sysdeps/unix/sysv/linux/sys/futex.h > create mode 100644 sysdeps/unix/sysv/linux/tst-futex.c >
On 18/08/26 14:57, Adhemerval Zanella Netto wrote: > > > On 14/08/26 15:36, André Almeida wrote: >> Hi folks, >> >> Based on a talk on last LPC by Carlos O'Donell[1], I'm sending this patch as a >> starting point to add the futex_waitv() syscall wrapper. >> >> I tried to base myself on the work done for others wrappers, but I see that >> there are missing details in my implementation, so I'm seeking guidance on how >> to approach this. >> > > > I will try to create POC so we can check if it makes sense. I create a POC on personal branch for a possible futex interface [1]. Some design notes: * Only the well-defined subset of futex(2) is exposed: wait, timed wait, wake, value-checked requeue, and futex_waitv. The racy unchecked FUTEX_REQUEUE, the removed FUTEX_FD, the error-prone FUTEX_WAKE_OP, bitset matching, and the PI operations are deliberately not exposed. * Survey of real futex users (libgomp, libitm, libstdc++ C++11/C++20 tiers, libgo, libc++, OpenMP runtime, scudo, sanitizers) shows every usage in the wild is expressible with this set. The only caller-side adaptation anywhere is relative→absolute timeout conversion (libgo, libc++). * For the futex_* interfaces I also added a 32-bit interface (which I suggested against). It seems that libstc++ does not use _TIME_BITS and issues the syscall directly (and it always use the 32 bit time_t futex one, which is different issue). It makes a possible integration easier and it also seems expected to follow suit other syscall that still have 32-bit time_t support. * futex_waitv is only provided for 64-bit time_t. * All of them uses the default -1/errno for error reporting, instead of the pthread like way I suggested. With the only exception of libgo from gcc, all other futexes usage are through 'syscall' and they handle errors through the usual errno mechanism. * Flags follow the kernel convention: zero means process-shared, FUTEX_PRIVATE_FLAG selects the private fast path. So the same value works across all five functions, including futex_waitv's per-waiter FUTEX2_PRIVATE. * futex_timedwait takes an absolute timeout with an explicit clockid, implemented with FUTEX_WAIT_BITSET/FUTEX_BITSET_MATCH_ANY to avoid the relative-only CLOCK_MONOTONIC quirk of FUTEX_WAIT. Pre-epoch timeouts are reported as ETIMEDOUT instead of the kernel's EINVAL (as we do for other syscalls). * The exported FUTEX2_* constants cover only what the syscall accepts today (FUTEX2_SIZE_U32, FUTEX2_PRIVATE, FUTEX2_NUMA, FUTEX2_MPOL, FUTEX_NO_NODE). The unimplemented sizes are omitted. [1] https://sourceware.org/git?p=glibc.git;a=shortlog;h=refs/heads/azanella/futex-wrappers
Hi Adhemerval, Em 20/08/2026 14:41, Adhemerval Zanella Netto escreveu: > > > On 18/08/26 14:57, Adhemerval Zanella Netto wrote: >> >> >> On 14/08/26 15:36, André Almeida wrote: >>> Hi folks, >>> >>> Based on a talk on last LPC by Carlos O'Donell[1], I'm sending this patch as a >>> starting point to add the futex_waitv() syscall wrapper. >>> >>> I tried to base myself on the work done for others wrappers, but I see that >>> there are missing details in my implementation, so I'm seeking guidance on how >>> to approach this. >>> >> >> >> I will try to create POC so we can check if it makes sense. > I create a POC on personal branch for a possible futex interface [1]. Some design > notes: > > * Only the well-defined subset of futex(2) is exposed: wait, timed wait, wake, > value-checked requeue, and futex_waitv. The racy unchecked FUTEX_REQUEUE, the > removed FUTEX_FD, the error-prone FUTEX_WAKE_OP, bitset matching, and the PI > operations are deliberately not exposed. > > * Survey of real futex users (libgomp, libitm, libstdc++ C++11/C++20 tiers, libgo, > libc++, OpenMP runtime, scudo, sanitizers) shows every usage in the wild is > expressible with this set. The only caller-side adaptation anywhere is > relative→absolute timeout conversion (libgo, libc++). > > * For the futex_* interfaces I also added a 32-bit interface (which I suggested > against). It seems that libstc++ does not use _TIME_BITS and issues the syscall > directly (and it always use the 32 bit time_t futex one, which is different > issue). It makes a possible integration easier and it also seems expected > to follow suit other syscall that still have 32-bit time_t support. > > * futex_waitv is only provided for 64-bit time_t. > > * All of them uses the default -1/errno for error reporting, instead of the > pthread like way I suggested. With the only exception of libgo from gcc, all > other futexes usage are through 'syscall' and they handle errors through the > usual errno mechanism. > > * Flags follow the kernel convention: zero means process-shared, FUTEX_PRIVATE_FLAG > selects the private fast path. So the same value works across all five functions, > including futex_waitv's per-waiter FUTEX2_PRIVATE. > > * futex_timedwait takes an absolute timeout with an explicit clockid, implemented > with FUTEX_WAIT_BITSET/FUTEX_BITSET_MATCH_ANY to avoid the relative-only > CLOCK_MONOTONIC quirk of FUTEX_WAIT. Pre-epoch timeouts are reported as ETIMEDOUT > instead of the kernel's EINVAL (as we do for other syscalls). > > * The exported FUTEX2_* constants cover only what the syscall accepts today > (FUTEX2_SIZE_U32, FUTEX2_PRIVATE, FUTEX2_NUMA, FUTEX2_MPOL, FUTEX_NO_NODE). The > unimplemented sizes are omitted. > > [1] https://sourceware.org/git?p=glibc.git;a=shortlog;h=refs/heads/azanella/futex-wrappers Thank you! I had a look and I believe this is the right direction for the futex wrappers. Please let me know how can I cooperate with this effort, if there's any patch left to be written, if you need tests or so.
On 21/08/26 16:18, André Almeida wrote: > Hi Adhemerval, > > Em 20/08/2026 14:41, Adhemerval Zanella Netto escreveu: >> >> >> On 18/08/26 14:57, Adhemerval Zanella Netto wrote: >>> >>> >>> On 14/08/26 15:36, André Almeida wrote: >>>> Hi folks, >>>> >>>> Based on a talk on last LPC by Carlos O'Donell[1], I'm sending this patch as a >>>> starting point to add the futex_waitv() syscall wrapper. >>>> >>>> I tried to base myself on the work done for others wrappers, but I see that >>>> there are missing details in my implementation, so I'm seeking guidance on how >>>> to approach this. >>>> >>> >>> >>> I will try to create POC so we can check if it makes sense. >> I create a POC on personal branch for a possible futex interface [1]. Some design >> notes: >> >> * Only the well-defined subset of futex(2) is exposed: wait, timed wait, wake, >> value-checked requeue, and futex_waitv. The racy unchecked FUTEX_REQUEUE, the >> removed FUTEX_FD, the error-prone FUTEX_WAKE_OP, bitset matching, and the PI >> operations are deliberately not exposed. >> >> * Survey of real futex users (libgomp, libitm, libstdc++ C++11/C++20 tiers, libgo, >> libc++, OpenMP runtime, scudo, sanitizers) shows every usage in the wild is >> expressible with this set. The only caller-side adaptation anywhere is >> relative→absolute timeout conversion (libgo, libc++). >> >> * For the futex_* interfaces I also added a 32-bit interface (which I suggested >> against). It seems that libstc++ does not use _TIME_BITS and issues the syscall >> directly (and it always use the 32 bit time_t futex one, which is different >> issue). It makes a possible integration easier and it also seems expected >> to follow suit other syscall that still have 32-bit time_t support. >> >> * futex_waitv is only provided for 64-bit time_t. >> >> * All of them uses the default -1/errno for error reporting, instead of the >> pthread like way I suggested. With the only exception of libgo from gcc, all >> other futexes usage are through 'syscall' and they handle errors through the >> usual errno mechanism. >> >> * Flags follow the kernel convention: zero means process-shared, FUTEX_PRIVATE_FLAG >> selects the private fast path. So the same value works across all five functions, >> including futex_waitv's per-waiter FUTEX2_PRIVATE. >> >> * futex_timedwait takes an absolute timeout with an explicit clockid, implemented >> with FUTEX_WAIT_BITSET/FUTEX_BITSET_MATCH_ANY to avoid the relative-only >> CLOCK_MONOTONIC quirk of FUTEX_WAIT. Pre-epoch timeouts are reported as ETIMEDOUT >> instead of the kernel's EINVAL (as we do for other syscalls). >> >> * The exported FUTEX2_* constants cover only what the syscall accepts today >> (FUTEX2_SIZE_U32, FUTEX2_PRIVATE, FUTEX2_NUMA, FUTEX2_MPOL, FUTEX_NO_NODE). The >> unimplemented sizes are omitted. >> >> [1] https://sourceware.org/git?p=glibc.git;a=shortlog;h=refs/heads/azanella/futex-wrappers > Thank you! I had a look and I believe this is the right direction for the futex wrappers. > > Please let me know how can I cooperate with this effort, if there's any patch left to be written, if you need tests or so. I will send a patchset to review.
On 8/14/26 2:36 PM, André Almeida wrote: > Hi folks, > > Based on a talk on last LPC by Carlos O'Donell[1], I'm sending this patch as a > starting point to add the futex_waitv() syscall wrapper. Back from vacation :-) It seems like Adhemerval is going to roll this into a bigger series. > I tried to base myself on the work done for others wrappers, but I see that > there are missing details in my implementation, so I'm seeking guidance on how > to approach this. Thank you for submitting this! I've reviewed Adhemerval's RFC and I agree with the direction. > Thanks! > André > > [1] https://lpc.events/event/19/contributions/2220/ > > André Almeida (2): > Linux: Add futex_waitv > misc: tst-futex: Create futex test > > include/sys/futex.h | 4 ++ > sysdeps/unix/sysv/linux/Makefile | 3 + > sysdeps/unix/sysv/linux/futex_waitv.c | 32 +++++++++ > sysdeps/unix/sysv/linux/sys/futex.h | 24 +++++++ > sysdeps/unix/sysv/linux/tst-futex.c | 93 +++++++++++++++++++++++++++ > 5 files changed, 156 insertions(+) > create mode 100644 include/sys/futex.h > create mode 100644 sysdeps/unix/sysv/linux/futex_waitv.c > create mode 100644 sysdeps/unix/sysv/linux/sys/futex.h > create mode 100644 sysdeps/unix/sysv/linux/tst-futex.c >