summaryrefslogtreecommitdiffstats
path: root/man2/futex.2
diff options
context:
space:
mode:
Diffstat (limited to 'man2/futex.2')
-rw-r--r--man2/futex.288
1 files changed, 38 insertions, 50 deletions
diff --git a/man2/futex.2 b/man2/futex.2
index 949e22bf9..43b107543 100644
--- a/man2/futex.2
+++ b/man2/futex.2
@@ -19,7 +19,7 @@
.\" FIXME Do we need to add some text regarding Torvald Riegel's 2015-01-24 mail
.\" http://thread.gmane.org/gmane.linux.kernel/1703405/focus=1873242
.\"
-.TH futex 2 2023-02-05 "Linux man-pages 6.03"
+.TH futex 2 2023-05-03 "Linux man-pages 6.05.01"
.SH NAME
futex \- fast user-space locking
.SH LIBRARY
@@ -1738,9 +1738,10 @@ and the timeout expired before the operation completed.
.\"
.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.\"
-.SH VERSIONS
-Futexes were first made available in a stable kernel release
-with Linux 2.6.0.
+.SH STANDARDS
+Linux.
+.SH HISTORY
+Linux 2.6.0.
.PP
Initial futex support was merged in Linux 2.5.7 but with different
semantics from what was described above.
@@ -1748,19 +1749,6 @@ A four-argument system call with the semantics
described in this page was introduced in Linux 2.5.40.
A fifth argument was added in Linux 2.5.70,
and a sixth argument was added in Linux 2.6.7.
-.SH STANDARDS
-This system call is Linux-specific.
-.SH NOTES
-Several higher-level programming abstractions are implemented via futexes,
-including POSIX semaphores and
-various POSIX threads synchronization mechanisms
-(mutexes, condition variables, read-write locks, and barriers).
-.\" TODO FIXME(Torvald) Above, we cite this section and claim it contains
-.\" details on the synchronization semantics; add the C11 equivalents
-.\" here (or whatever we find consensus for).
-.\"
-.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
-.\"
.SH EXAMPLES
The program below demonstrates use of futexes in a program where a parent
process and a child process use a pair of futexes located inside a
@@ -1793,10 +1781,10 @@ Child (18535) 4
.\" SRC BEGIN (futex.c)
.EX
/* futex_demo.c
-
+\&
Usage: futex_demo [nloops]
(Default: 5)
-
+\&
Demonstrate the use of futexes in a program where parent and child
use a pair of futexes located inside a shared anonymous mapping to
synchronize access to a shared resource: the terminal. The two
@@ -1817,9 +1805,9 @@ Child (18535) 4
#include <sys/time.h>
#include <sys/wait.h>
#include <unistd.h>
-
+\&
static uint32_t *futex1, *futex2, *iaddr;
-
+\&
static int
futex(uint32_t *uaddr, int futex_op, uint32_t val,
const struct timespec *timeout, uint32_t *uaddr2, uint32_t val3)
@@ -1827,111 +1815,111 @@ futex(uint32_t *uaddr, int futex_op, uint32_t val,
return syscall(SYS_futex, uaddr, futex_op, val,
timeout, uaddr2, val3);
}
-
+\&
/* Acquire the futex pointed to by \[aq]futexp\[aq]: wait for its value to
become 1, and then set the value to 0. */
-
+\&
static void
fwait(uint32_t *futexp)
{
long s;
const uint32_t one = 1;
-
+\&
/* atomic_compare_exchange_strong(ptr, oldval, newval)
atomically performs the equivalent of:
-
+\&
if (*ptr == *oldval)
*ptr = newval;
-
+\&
It returns true if the test yielded true and *ptr was updated. */
-
+\&
while (1) {
-
+\&
/* Is the futex available? */
if (atomic_compare_exchange_strong(futexp, &one, 0))
break; /* Yes */
-
+\&
/* Futex is not available; wait. */
-
+\&
s = futex(futexp, FUTEX_WAIT, 0, NULL, NULL, 0);
if (s == \-1 && errno != EAGAIN)
err(EXIT_FAILURE, "futex\-FUTEX_WAIT");
}
}
-
+\&
/* Release the futex pointed to by \[aq]futexp\[aq]: if the futex currently
has the value 0, set its value to 1 and then wake any futex waiters,
so that if the peer is blocked in fwait(), it can proceed. */
-
+\&
static void
fpost(uint32_t *futexp)
{
long s;
const uint32_t zero = 0;
-
+\&
/* atomic_compare_exchange_strong() was described
in comments above. */
-
+\&
if (atomic_compare_exchange_strong(futexp, &zero, 1)) {
s = futex(futexp, FUTEX_WAKE, 1, NULL, NULL, 0);
if (s == \-1)
err(EXIT_FAILURE, "futex\-FUTEX_WAKE");
}
}
-
+\&
int
main(int argc, char *argv[])
{
pid_t childPid;
unsigned int nloops;
-
+\&
setbuf(stdout, NULL);
-
+\&
nloops = (argc > 1) ? atoi(argv[1]) : 5;
-
+\&
/* Create a shared anonymous mapping that will hold the futexes.
Since the futexes are being shared between processes, we
subsequently use the "shared" futex operations (i.e., not the
ones suffixed "_PRIVATE"). */
-
+\&
iaddr = mmap(NULL, sizeof(*iaddr) * 2, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_SHARED, \-1, 0);
if (iaddr == MAP_FAILED)
err(EXIT_FAILURE, "mmap");
-
+\&
futex1 = &iaddr[0];
futex2 = &iaddr[1];
-
+\&
*futex1 = 0; /* State: unavailable */
*futex2 = 1; /* State: available */
-
+\&
/* Create a child process that inherits the shared anonymous
mapping. */
-
+\&
childPid = fork();
if (childPid == \-1)
err(EXIT_FAILURE, "fork");
-
+\&
if (childPid == 0) { /* Child */
for (unsigned int j = 0; j < nloops; j++) {
fwait(futex1);
printf("Child (%jd) %u\en", (intmax_t) getpid(), j);
fpost(futex2);
}
-
+\&
exit(EXIT_SUCCESS);
}
-
+\&
/* Parent falls through to here. */
-
+\&
for (unsigned int j = 0; j < nloops; j++) {
fwait(futex2);
printf("Parent (%jd) %u\en", (intmax_t) getpid(), j);
fpost(futex1);
}
-
+\&
wait(NULL);
-
+\&
exit(EXIT_SUCCESS);
}
.EE
@@ -1977,7 +1965,7 @@ Drepper, U., 2011. \fIFutexes Are Tricky\fP,
.UR http://www.akkadia.org/drepper/futex.pdf
.UE
.PP
-Futex example library, futex-*.tar.bz2 at
+Futex example library, futex\-*.tar.bz2 at
.br
.UR https://mirrors.kernel.org\:/pub\:/linux\:/kernel\:/people\:/rusty/
.UE