io_uring_prep_futex_wait(3)

πŸ“¦
version 2.15 Β· 2 versions
, in alpine 3.24, arch rolling, fedora 44, nixpkgs unstable, ubuntu resolute, ubuntu stonking

πŸ’– io_uring_prep_futex_wait β€” the liburing manual, bestie edition πŸ’–

okay so. you're in the liburing manual, section 3, and the star of today's show is io_uring_prep_futex_wait. it's giving "make my ring wait on a futex without blocking a thread" and honestly? iconic. let's get into it. πŸ¦‹


✨ NAME ✨

io_uring_prep_futex_wait β€” bestie, it prepares a futex wait request. that's it. that's the whole job. πŸ’…


🌸 SYNOPSIS 🌸

#include <linux/futex.h>
#include <unistd.h>
#include <liburing.h>

void io_uring_prep_futex_wait(struct io_uring_sqe *sqe,
                              const uint32_t *futex,
                              uint64_t val,
                              uint64_t mask,
                              uint32_t futex_flags,
                              unsigned int flags);

look at her. six arguments. main character energy fr fr. ✨


πŸŽ€ DESCRIPTION πŸŽ€

so the way that io_uring_prep_futex_wait(3) works is: it preps a futex wait request. you hand it a submission queue entry sqe, and it sets that sqe up to wait on a futex at address futex β€” but only if it still has the value val. like, no cap, the value has to still match or the wait just doesn't happen. 😭

on top of that you're passing futex2(2) flags in futex_flags, and the io_uring futex flags in flags.

now, mask β€” you can set this to a specific bitset mask, and the waking side will match against it to decide who gets woken up. so it's lowkey a little VIP list. 🎟️ if you want to always get woken, an application may use FUTEX_BITSET_MATCH_ANY. no faves, everyone gets in. πŸ’–

heads up bestie: futex_flags follows the futex2(2) flags, not the futex(2) v1 interface flags. don't mix them up, i'm begging. πŸ™ˆ

and flags? currently unused, so 0 must be passed. zero. nothing. she's not taking applications right now. πŸ’€

this function prepares an async futex(2) wait request β€” go read that man page for the details, it's the source of truth. and ngl, a fun lil fact: the io_uring futex wait request is similar to the FUTEX_WAIT_BITSET operation, because FUTEX_WAIT is a strict subset of that. subset! she contains multitudes. πŸ‘‘

Available since kernel 6.7. ⭐


πŸ’« RETURN VALUE πŸ’«

None. literally none. it returns nothing, it's above such things. 🧚


🌈 ERRORS 🌈

the CQE res field is where the result of the operation lives. see the related man page for details on possible values. πŸ‘€

and here's the thing that trips people up: synchronous system calls return -1 on failure and set errno to the actual error value β€” but io_uring never uses errno. instead it returns the negated errno directly in the CQE res field. so if you're out here checking errno after an io_uring op, bestie, no you're not. πŸ’€ check res.


πŸ”₯ NOTES πŸ”₯

okay so unlike the sync futex syscalls that wait on a futex, io_uring does not support passing in a timeout for the request. sorry. no timeout parameter, she said no. 😭

instead, applications are encouraged to use a linked timeout to abort the futex request at a given time, if desired. that's the move. link it up. πŸ”—


🫢 SEE ALSO 🫢


and that's the whole page, bestie, you ate it. πŸ“

this was liburing-2.5, dated Sep 29, 2023, and it's still serving io_uring_prep_futex_wait(3) realness to this very day. go prep some sqes, ily, bye πŸ’œβœ¨

πŸ“¦ where this page comes from