Nov 24, 2025

[futex2] io_uring_prep_futex_waitv

man:
io_uring_prep_futex_waitv

Why futex2?
  1. Wait on Multiple Mutexes (futex_waitv)
    The single biggest driver for futex2 was the gaming industry (Valve/CodeWeavers).

    The Problem: Windows has a function called WaitForMultipleObjects. It allows a thread to sleep until any one of a list of locks/events becomes available.

    Game Engine Logic: "Sleep until the GPU is done OR a network packet arrives OR the user presses a key."

    1. Old Linux futex: Could only wait on one address. To emulate Windows, Wine had to create complex polling loops or use expensive eventfd file descriptors, killing performance.
    2. The futex2 Solution: The new syscall sys_futex_waitv accepts an array of futexes. The kernel puts the thread to sleep and wakes it up if any of the futexes in the array are triggered.

  2. Variable Sized Locks (Not just 32-bit)
    The original sys_futex was strictly designed for 32-bit integers.
    If you wanted a tiny lock (boolean flag), you wasted 32 bits.
    If you wanted a 64-bit lock (e.g., storing a pointer or a full counter), you couldn't do it atomically via the kernel.

    futex2 introduces explicit sizing:
    1. 8-bit: Great for boolean flags.
    2. 16-bit: Useful for small counters.
    3. 32-bit: Legacy standard.
    4. 64-bit: Crucial for modern 64-bit pointer tagging and high-contention counters

    This allows languages like Rust, Go, or C++ to implement synchronization primitives that map naturally to their native data types without padding or casting.
#include <linux/futex.h>
#include <unistd.h>
#include <liburing.h>

struct futex_waitv {
    uint64_t val;  // Expected value
    uint64_t uaddr; // Address of the futex
    uint32_t flags; // Flags (e.g., 32-bit vs 64-bit)
    uint32_t __reserved;
};

// Syscall prototype
// blocks until at least one futex wakes up
syscall(SYS_futex_waitv, struct futex_waitv *waiters, unsigned int nr_futexes, ...);

// io_uring lib api
void io_uring_prep_futex_waitv(struct io_uring_sqe *sqe,
	struct futex_waitv *futexv,
	uint32_t nr_futex,
	unsigned int flags);

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.