Re: [PATCH v7] futex_waitv.2: new page
From: Alejandro Colomar <alx@kernel.org>
Date: 2026-02-14 17:32:20
Hi наб, On 2026-02-11T15:44:20+0100, наб wrote:
Signed-off-by: Ahelenia Ziemiańska <redacted> --- Range-diff against v5:
[...] Thanks!
quoted hunk ↗ jump to hunk
man/man2/futex_waitv.2 | 421 +++++++++++++++++++++++++++++++++++++++++ man/man7/futex.7 | 9 +- 2 files changed, 428 insertions(+), 2 deletions(-) create mode 100644 man/man2/futex_waitv.2diff --git u/man/man2/futex_waitv.2 p/man/man2/futex_waitv.2 new file mode 100644 index 000000000..a1eeb8ce8 --- /dev/null +++ p/man/man2/futex_waitv.2@@ -0,0 +1,421 @@
[...]
+.SH SYNOPSIS +.nf +.BR "#include <linux/futex.h>" " /* Definition of " FUTEX* " constants */"
Out of curiosity, why are some macros FUTEX2_* instead of FUTEX_*? (if you know)
+.BR "#include <sys/syscall.h>" " /* Definition of " SYS_* " constants */" +.B #include <unistd.h> +.B #include <time.h> +.P +.SH ERRORS
[...]
+.TP +.B EINVAL +.I n +was not in the range +.RB [ 1 , +.I FUTEX_WAITV_MAX +(128)].
Ahhh, so 128 is the value of FUTEX_WAITV_MAX, not its argument. I prefer not showing that value here. Let's just say .IR FUTEX_WAITV_MAX ]. In general, we don't hard-code magic values unless users *need* to know them. This makes it more evident that if users rely on a specific value, that may carry portability problems. [...]
+.TP +.B EINVAL +.B FUTEX2_NUMA +was set in +.IR waiters []. flags , +and the NUMA word +(which is the same size as the futex word) +is too small to contain the index of the biggest NUMA domain +(for example, +.B FUTEX2_SIZE_U8 +and there are more than 255 NUMA domains).
Is it 255 or 256? I assume it's a 0-based index, so I'd expect there to fit 256 indices in a u8. [...]
+.SH NOTES +.BR FUTEX2_SIZE_U8 , +.BR FUTEX2_SIZE_U16 , +and +.B FUTEX2_SIZE_U64 +where +.I .val +and +.I *.uaddr
This should also be .uaddr[]
+are 8, 16, or 64 bits are defined, but not implemented +.RB ( EINVAL ).
[...]
+.SH EXAMPLES
[...]
+.EX
+.RB $\~ ./futex_waitv
+153 153 153 237 100 245 177 127 215 61
+ 122!
+ 200!
+ 254!
+306 306!
+ 306!
+ 354!
+ 430!
+ 474!
+ 490!
+Connection timed out
+.EE
+.P
+.\" SRC BEGIN (futex_waitv.c)
+.EX
+#include <errno.h>
+#include <inttypes.h>
+#include <linux/futex.h>
+#include <pthread.h>
+#include <stdatomic.h>
+#include <stdcountof.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <time.h>
+#include <unistd.h>
+\&
+static inline long
+my_futex_wait_private(_Atomic uint32_t *uaddr, uint32_t val)
+{
+ return syscall(SYS_futex, uaddr, FUTEX_WAKE_PRIVATE, val);
+}
+\&
+static inline long
+my_futex_waitv(unsigned int n;
+ struct futex_waitv waiters[n], unsigned int n,
+ unsigned int flags, const struct timespec *timeout,
+ clockid_t clockid)
+{
+ return syscall(SYS_futex_waitv, waiters, n, flags, timeout, clockid);
+}
+\&
+void *
+worker(void *arg)
+{
+ _Atomic uint32_t *futex = arg;
+\&
+ usleep(*futex * 10000);
+ *futex *= 2;
+ my_futex_wait_private(futex, 1);
+ return NULL;
+}
+\&
+int
+main(void)
+{
+ _Atomic uint32_t futexes[10];
+ uint8_t init[countof(futexes)];
+ struct futex_waitv waiters[countof(futexes)] = {};
+ int i;
+\&
+ getentropy(init, sizeof(init));
$ make -R lint build-all check CC=/opt/local/gnu/gcc/cap4/bin/gcc
...
.tmp/man/man2/futex_waitv.2.d/futex_waitv.c:50:6: error: ignoring return value of ‘getentropy’ declared with attribute ‘warn_unused_result’ [-Werror=unused-result]
50 | getentropy(init, sizeof(init));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
At top level:
cc1: note: unrecognized command-line option ‘-Wno-reserved-identifier’ may have been intended to silence earlier diagnostics
cc1: all warnings being treated as errors
make: *** [/srv/alx/src/linux/man-pages/man-pages/contrib/share/mk/build/examples/cc.mk:30: .tmp/man/man2/futex_waitv.2.d/futex_waitv.o] Error 1
+ init[0] = init[1] = init[2];
+ for (i = 0; i < countof(futexes); ++i) {
+ printf("%" PRIu8 "\[rs]t", init[i]);
+ atomic_init(&futexes[i], init[i]);
+ pthread_create(&(pthread_t){}, NULL, worker, &futexes[i]);
+ }
+ putchar('\[rs]n');Here and elsewhere in the example: \[aq] instea of '
+\&
+ for (i = 0; i < countof(futexes); ++i) {
+ waiters[i].val = futexes[i];
+ waiters[i].uaddr = (uintptr_t)&futexes[i];Please add a space between casts and the expression their operand.
+ waiters[i].flags = FUTEX2_SIZE_U32 | FUTEX2_PRIVATE;
+ }
+ for (;;) {
+ struct timespec timeout;
+ int woke;
+\&
+ clock_gettime(CLOCK_MONOTONIC, &timeout);
+ timeout.tv_sec += 1;
+\&
+ woke = my_futex_waitv(waiters, countof(futexes), 0, &timeout, CLOCK_MONOTONIC);
+ if (woke == -1 && (errno != EAGAIN && errno != EWOULDBLOCK))
$ make -R lint-man-dash
make: warning: undefined variable 'GNUMAKEFLAGS'
PCRE2GREP .tmp/man/man2/futex_waitv.2.lint-man.dash.touch
lint-man-dash: .tmp/man/man2/futex_waitv.2: Unescaped dash:
397: if (woke == -1 && (errno != EAGAIN && errno != EWOULDBLOCK))
make: *** [/srv/alx/src/linux/man-pages/man-pages/contrib/share/mk/lint/man/dash.mk:26: .tmp/man/man2/futex_waitv.2.lint-man.dash.touch] Error 1
Have a lovely day!
Alex
quoted hunk ↗ jump to hunk
+ break; +\& + for (i = 0; i < countof(futexes); ++i) { + if (futexes[i] != waiters[i].val) + printf("%" PRIu32 "%s", futexes[i], i == woke ? "!" : ""); + putchar('\[rs]t'); + } + putchar('\[rs]n'); +\& + for (i = 0; i < countof(futexes); ++i) + waiters[i].val = futexes[i]; + } + fprintf(stderr, "%s\[rs]n", strerror(errno)); +} +.EE +.\" SRC END +.SH SEE ALSO +.BR futex (2), +.BR FUTEX_WAIT (2const), +.BR FUTEX_WAKE (2const), +.BR futex (7) +.P +Kernel source file +.I Documentation/userspace-api/futex2.rstdiff --git u/man/man7/futex.7 p/man/man7/futex.7 index 51c5d5d9b..d271144ff 100644 --- u/man/man7/futex.7 +++ p/man/man7/futex.7@@ -45,7 +45,9 @@ .SS Semantics Any futex operation starts in user space, but it may be necessary to communicate with the kernel using the .BR futex (2) -system call. +or +.BR futex_waitv (2) +system calls. .P To "up" a futex, execute the proper assembler instructions that will cause the host CPU to atomically increment the integer.@@ -72,7 +74,9 @@ .SS Semantics .P The .BR futex (2) -system call can optionally be passed a timeout specifying how long +and +.BR futex_waitv (2) +system calls can optionally be passed a timeout specifying how long the kernel should wait for the futex to be upped. In this case, semantics are more complex and the programmer is referred@@ -107,6 +111,7 @@ .SH NOTES .SH SEE ALSO .BR clone (2), .BR futex (2), +.BR futex_waitv (2), .BR get_robust_list (2), .BR set_robust_list (2), .BR set_tid_address (2),-- 2.39.5
-- <https://www.alejandro-colomar.es>
Attachments
- signature.asc [application/pgp-signature] 833 bytes