FUTEX_CMP_REQUEUE_PI(2const)

โœจ FUTEX_CMP_REQUEUE_PI(2const) โœจ

okay bestie, buckle up ๐Ÿ’– this is the manual page for FUTEX_CMP_REQUEUE_PI(2const) โ€” a whole constant that you pass to the futex syscall. no cap, this is some deeply unhinged kernel-level stuff and we're gonna get through it together ๐Ÿซถ


๐ŸŒธ LIBRARY ๐ŸŒธ

Standard C library (libc, -lc) โ€” yes girl, the regular one ๐Ÿ’…


๐ŸŽ€ SYNOPSIS ๐ŸŽ€

lowkey the incantation goes like this:

#include <linux/futex.h>  /* Definition of FUTEX_* constants */
#include <sys/syscall.h>  /* Definition of SYS_* constants */
#include <unistd.h>

long syscall(SYS_futex, uint32_t *uaddr, FUTEX_CMP_REQUEUE_PI, 1,
             uint32_t val2, uint32_t *uaddr2,
             uint32_t val3);

like I said. the whole thing. SYS_futex, uaddr, the constant, 1, val2, uaddr2, val3. every single one matters, don't skip any ๐Ÿ˜ญ


๐Ÿ’œ DESCRIPTION ๐Ÿ’œ

so basically, this operation is the PI-aware glow-up of FUTEX_CMP_REQUEUE(2const). it's giving... upgrade. ๐Ÿ‘‘

what it does: it requeues waiters that are blocked via FUTEX_WAIT_REQUEUE_PI(2const) on uaddr, moving them from a non-PI source futex (uaddr) over to a PI target futex (uaddr2). it's literally transferring the girlies to a new queue. โœจ

here's the difference from FUTEX_CMP_REQUEUE(2const), and it's a big one: this operation wakes up a maximum of 1 waiter that's waiting on the futex at uaddr. why? because the main point is to avoid a thundering herd ๐ŸŽ๐Ÿ’€ โ€” nobody wants a stampede at the door. all the remaining waiters get removed from the wait queue of the source futex at uaddr and added to the wait queue of the target futex at uaddr2.

and the val2 and val3 arguments? they serve the exact same purposes as they do for FUTEX_CMP_REQUEUE(2const). same job, different day ๐Ÿซถ


โญ RETURN VALUE โญ

if things go wrong: -1 gets returned, and errno is set to tell you what went wrong. classic ๐Ÿ˜ญ

if things go right: FUTEX_CMP_REQUEUE_PI returns the total number of waiters that were woken up or requeued to the futex for the futex word at uaddr2.

and listen โ€” if that value is greater than 1, then the difference is the number of waiters requeued to the futex for the futex word at uaddr2. math is math, bestie ๐Ÿงฎ


๐Ÿ”ฅ ERRORS ๐Ÿ”ฅ

also see futex(2) for the broader lore ๐Ÿ‘€

  • EAGAIN โ€” the value pointed to by uaddr is not equal to the expected value val3. mismatch era ๐Ÿ’€
  • EAGAIN โ€” the futex owner thread ID of uaddr2 is about to exit, but hasn't yet handled the internal state cleanup. try again (the audacity, honestly).
  • EDEADLK โ€” the futex word at uaddr is already locked by the caller. you did this to yourself bestie ๐Ÿ™ˆ
  • EDEADLK โ€” while requeueing a waiter to the PI futex for the futex word at uaddr2, the kernel detected a deadlock. not the vibe. ๐Ÿ˜ญ
  • EFAULT โ€” uaddr2 did not point to a valid user-space address.
  • EINVAL โ€” uaddr2 does not point to a valid object โ€” that is, the address is not four-byte-aligned.
  • EINVAL โ€” uaddr equals uaddr2 (i.e., an attempt was made to requeue to the same futex). girl, that's the same queue. ๐Ÿ’€
  • EINVAL โ€” the kernel detected an inconsistency between the user-space state at uaddr2 and the kernel state; that is, the kernel detected a waiter which waits via FUTEX_WAIT(2const) or FUTEX_WAIT_BITSET(2const) on uaddr2.
  • EINVAL โ€” the kernel detected an inconsistency between the user-space state at uaddr and the kernel state; that is, the kernel detected a waiter which waits via FUTEX_WAIT(2const) or FUTEX_WAIT_BITSET(2const) on uaddr.
  • EINVAL โ€” the kernel detected an inconsistency between the user-space state at uaddr and the kernel state; that is, the kernel detected a waiter which waits on uaddr via FUTEX_LOCK_PI(2const) or FUTEX_LOCK_PI2(2const) (instead of FUTEX_WAIT_REQUEUE_PI). wrong door, ma'am ๐Ÿšช
  • EINVAL โ€” an attempt was made to requeue a waiter to a futex other than that specified by the matching FUTEX_WAIT_REQUEUE_PI call for that waiter.
  • EINVAL โ€” the fourth argument is not 1. nope, it literally has to be 1. periodt.
  • ENOMEM โ€” the kernel could not allocate memory to hold state information. broke era ๐Ÿ’ธ
  • ENOSYS โ€” a run-time check determined that the operation is not available. the PI-futex operations are not implemented on all architectures and are not supported on some CPU variants. it's not you, it's the hardware ๐Ÿฅฒ
  • EPERM โ€” the caller is not allowed to attach itself to the futex at uaddr2. (this may be caused by a state corruption in user space.) ๐Ÿšจ
  • ESRCH โ€” the thread ID in the futex word at uaddr does not exist.
  • ESRCH โ€” the thread ID in the futex word at uaddr2 does not exist.

๐Ÿฆ‹ STANDARDS ๐Ÿฆ‹

Linux. that's it, that's the standard. ๐Ÿ‘‘


๐ŸŒˆ HISTORY ๐ŸŒˆ

Linux 2.6.31 โ€” old money, lowkey vintage, still iconic โญ


๐Ÿ“ SEE ALSO ๐Ÿ“

  • futex(2) โ€” go read the parent page, bestie, it's the main character here ๐Ÿ’…

and that's the whole page, no crumbs left ๐Ÿ‘‘ this was FUTEX_CMP_REQUEUE_PI(2const) from Linux man-pages 6.20, dated 2025-09-21. slay, go forth and requeue responsibly ๐Ÿซถโœจ๐Ÿ’–

๐Ÿ“ฆ where this page comes from
  • arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
  • nixpkgs unstable: man-pages 6.20
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms