Hi наб, On 2026-02-14T21:48:01+0100, наб wrote: [...] > +static inline long > +my_futex_wait_private(_Atomic uint32_t *uaddr, uint32_t val) I just noticed this should be my_futex_wa{it => ke}_private(). Probably caused by my earlier confusion while reading these; sorry! > +{ > + 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; > +\& > + if (getentropy(init, sizeof(init))) > + err(EXIT_FAILURE, "getentropy"); > + 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(\[aq]\[rs]n\[aq]); > +\& > + for (i = 0; i < countof(futexes); ++i) { > + waiters[i].val = futexes[i]; > + waiters[i].uaddr = (uintptr_t) &futexes[i]; > + 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)) > + err(EXIT_FAILURE, "my_futex_waitv"); > +\& > + for (i = 0; i < countof(futexes); ++i) { > + if (futexes[i] != waiters[i].val) > + printf("%" PRIu32 "%s", futexes[i], i == woke ? "!" : ""); This line goes past the right margin, and could be trivially narrowed by using the new (C23) fixed-width length modifiers: alx@devuan:~/tmp$ cat pf.c #include #include int main(void) { int32_t i = 7; printf("%w32d\n", i); } alx@devuan:~/tmp$ gcc -Wall -Wextra pf.c alx@devuan:~/tmp$ ./a.out 7 So, the line would be: printf("%w32d%s", futexes[i], i == woke ? "!" : ""); > + putchar(\[aq]\[rs]t\[aq]); > + } > + putchar(\[aq]\[rs]n\[aq]); > +\& > + for (i = 0; i < countof(futexes); ++i) > + waiters[i].val = futexes[i]; > + } > +} Have a lovely night! Alex --