futex(7)

๐Ÿ’– futex(7) โ€” Miscellaneous Information Manual ๐Ÿ’–

okay bestie, gather round, we're talking about futex โ€” the fast user-space locking girlie of the Linux kernel ๐ŸŒธ


โœจ NAME โœจ

futex โ€” fast user-space locking ๐ŸŽ€


โœจ SYNOPSIS โœจ

#include <linux/futex.h>

โœจ DESCRIPTION โœจ

So the Linux kernel hands you futexes ("Fast user-space mutexes") as a lil building block ๐Ÿงฑ for fast user-space locking and semaphores. They are very basic on purpose, and that's exactly why they're so good for building higher-level locking abstractions on top of โ€” think mutexes, condition variables, read-write locks, barriers, and semaphores. iconic behavior, honestly ๐Ÿ‘‘

ngl, most programmers are NOT gonna be touching futexes directly. They're gonna be leaning on system libraries that were built on top of them, like the Native POSIX Thread Library (NPTL) โ€” see pthreads(7) for the tea โ˜•

A futex gets identified by a piece of memory that can be shared between processes or threads. And here's the cute part: across those different processes, the futex doesn't even need to have identical addresses. In its bare form, a futex has semaphore semantics โ€” it's a counter that can be incremented and decremented atomically, and processes can wait for the value to become positive ๐Ÿ’…

Futex operation happens entirely in user space in the noncontended case. The kernel only shows up to arbitrate the contended case. And since any sane design is gonna strive for noncontention, futexes are optimized for exactly that situation ๐Ÿฆ‹

In its bare form, a futex is an aligned integer that gets touched only by atomic assembler instructions. This integer is four bytes long on all platforms. Processes can share this integer using mmap(2), via shared memory segments, or just because they share memory space โ€” in which case the application is commonly called multithreaded ๐Ÿ’œ


๐ŸŒธ Semantics ๐ŸŒธ

Any futex operation starts in user space, but it may be necessary to communicate with the kernel using the futex(2) or futex_waitv(2) system calls.

To "up" a futex, you execute the proper assembler instructions that cause the host CPU to atomically increment the integer. Afterward, check if it has in fact changed from 0 to 1 โ€” if it did, there were no waiters and the operation is done โœจ This is the noncontended case, which is fast and should be common. slay.

In the contended case, the atomic increment changed the counter from -1 (or some other negative number ๐Ÿ™ˆ). If you detect that, it means there are waiters. User space should now set the counter to 1 and instruct the kernel to wake up any waiters using the FUTEX_WAKE operation.

Waiting on a futex, to "down" it, is the reverse operation. Atomically decrement the counter and check if it changed to 0 โ€” if it did, the operation is done and the futex was uncontended ๐Ÿซถ In all other circumstances, the process should set the counter to -1 and request that the kernel wait for another process to up the futex. This is done using the FUTEX_WAIT operation.

The futex(2) and 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 to futex(2) for more details. The same holds for asynchronous futex waiting. iykyk ๐Ÿ˜ญ


โœจ VERSIONS โœจ

Initial futex support was merged way back in Linux 2.5.7, but with different semantics from the ones described above ๐Ÿ™ˆ The current semantics are available from Linux 2.5.40 onward ๐Ÿ’…


โœจ NOTES โœจ

To reiterate (because this matters, bestie): bare futexes are not intended as an easy-to-use abstraction for end users. โŒ Implementors are expected to be assembly-literate and to have read the sources of the futex user-space library referenced below ๐Ÿ“š

This is not a beginner-friendly API. It is not a "just call it and vibe" API. It is a "you write assembly and you read the library source" API. no cap.

This manual page illustrates the most common use of the futex(2) primitives โ€” it is by no means the only one ๐ŸŒˆ


โœจ SEE ALSO โœจ


and that's the whole page, bestie ๐Ÿ’– this was brought to you by Linux man-pages 6.20, dated 2026-02-17, and it's the futex(7) girlies' moment โœจ๐Ÿฆ‹๐ŸŽ€ periodt ๐Ÿ‘‘

๐Ÿ“ฆ 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
  • ๐Ÿ“œ the page's license: MIT
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms