From: Alejandro Colomar Date: Thu, 29 May 2025 10:54:16 +0000 (+0200) Subject: man/man2/futex.2, man/man2const/FUTEX_WAKE_OP.2const: Split FUTEX_WAKE_OP from futex(2) X-Git-Tag: man-pages-6.15~43^2~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9bead1fb6aa464379819f6c60fa45b1ade8792e2;p=thirdparty%2Fman-pages.git man/man2/futex.2, man/man2const/FUTEX_WAKE_OP.2const: Split FUTEX_WAKE_OP from futex(2) Signed-off-by: Alejandro Colomar --- diff --git a/man/man2/futex.2 b/man/man2/futex.2 index b47d8f6e4..9b2b1f528 100644 --- a/man/man2/futex.2 +++ b/man/man2/futex.2 @@ -266,156 +266,8 @@ is one of the following: .BR FUTEX_REQUEUE (2const) .TQ .BR FUTEX_CMP_REQUEUE (2const) -.TP -.BR FUTEX_WAKE_OP " (since Linux 2.6.14)" -.\" commit 4732efbeb997189d9f9b04708dc26bf8613ed721 -.\" Author: Jakub Jelinek -.\" Date: Tue Sep 6 15:16:25 2005 -0700 -.\" FIXME. (Torvald) The glibc condvar implementation is currently being -.\" revised (e.g., to not use an internal lock anymore). -.\" It is probably more future-proof to remove this paragraph. -.\" [Torvald, do you have an update here?] -This operation was added to support some user-space use cases -where more than one futex must be handled at the same time. -The most notable example is the implementation of -.BR pthread_cond_signal (3), -which requires operations on two futexes, -the one used to implement the mutex and the one used in the implementation -of the wait queue associated with the condition variable. -.B FUTEX_WAKE_OP -allows such cases to be implemented without leading to -high rates of contention and context switching. -.IP -The -.B FUTEX_WAKE_OP -operation is equivalent to executing the following code atomically -and totally ordered with respect to other futex operations on -any of the two supplied futex words: -.IP -.in +4n -.EX -uint32_t oldval = *(uint32_t *) uaddr2; -*(uint32_t *) uaddr2 = oldval \f[I]op\f[] \f[I]oparg\f[]; -futex(uaddr, FUTEX_WAKE, val, 0, 0, 0); -if (oldval \f[I]cmp\f[] \f[I]cmparg\f[]) - futex(uaddr2, FUTEX_WAKE, val2, 0, 0, 0); -.EE -.in -.IP -In other words, -.B FUTEX_WAKE_OP -does the following: -.RS -.IP \[bu] 3 -saves the original value of the futex word at -.I uaddr2 -and performs an operation to modify the value of the futex at -.IR uaddr2 ; -this is an atomic read-modify-write memory access (i.e., using atomic -machine instructions of the respective architecture) -.IP \[bu] -wakes up a maximum of -.I val -waiters on the futex for the futex word at -.IR uaddr ; -and -.IP \[bu] -dependent on the results of a test of the original value of the -futex word at -.IR uaddr2 , -wakes up a maximum of -.I val2 -waiters on the futex for the futex word at -.IR uaddr2 . -.RE -.IP -The operation and comparison that are to be performed are encoded -in the bits of the argument -.IR val3 . -Pictorially, the encoding is: -.IP -.in +4n -.EX -+---+---+-----------+-----------+ -|op |cmp| oparg | cmparg | -+---+---+-----------+-----------+ - 4 4 12 12 <== # of bits -.EE -.in -.IP -Expressed in code, the encoding is: -.IP -.in +4n -.EX -#define FUTEX_OP(op, oparg, cmp, cmparg) \[rs] - (((op & 0xf) << 28) | \[rs] - ((cmp & 0xf) << 24) | \[rs] - ((oparg & 0xfff) << 12) | \[rs] - (cmparg & 0xfff)) -.EE -.in -.IP -In the above, -.I op -and -.I cmp -are each one of the codes listed below. -The -.I oparg -and -.I cmparg -components are literal numeric values, except as noted below. -.IP -The -.I op -component has one of the following values: -.IP -.in +4n -.EX -FUTEX_OP_SET 0 /* uaddr2 = oparg; */ -FUTEX_OP_ADD 1 /* uaddr2 += oparg; */ -FUTEX_OP_OR 2 /* uaddr2 |= oparg; */ -FUTEX_OP_ANDN 3 /* uaddr2 &= \[ti]oparg; */ -FUTEX_OP_XOR 4 /* uaddr2 \[ha]= oparg; */ -.EE -.in -.IP -In addition, bitwise ORing the following value into -.I op -causes -.I (1\~<<\~oparg) -to be used as the operand: -.IP -.in +4n -.EX -FUTEX_OP_ARG_SHIFT 8 /* Use (1 << oparg) as operand */ -.EE -.in -.IP -The -.I cmp -field is one of the following: -.IP -.in +4n -.EX -FUTEX_OP_CMP_EQ 0 /* if (oldval == cmparg) wake */ -FUTEX_OP_CMP_NE 1 /* if (oldval != cmparg) wake */ -FUTEX_OP_CMP_LT 2 /* if (oldval < cmparg) wake */ -FUTEX_OP_CMP_LE 3 /* if (oldval <= cmparg) wake */ -FUTEX_OP_CMP_GT 4 /* if (oldval > cmparg) wake */ -FUTEX_OP_CMP_GE 5 /* if (oldval >= cmparg) wake */ -.EE -.in -.IP -The return value of -.B FUTEX_WAKE_OP -is the sum of the number of waiters woken on the futex -.I uaddr -plus the number of waiters woken on the futex -.IR uaddr2 . -.\" -.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" -.\" +.TQ +.BR FUTEX_WAKE_OP (2const) .TP .BR FUTEX_WAIT_BITSET " (since Linux 2.6.25)" .\" commit cd689985cf49f6ff5c8eddc48d98b9d581d9475d @@ -1066,14 +918,6 @@ is set to indicate the error. The return value on success depends on the operation, as described in the following list: .TP -.B FUTEX_WAKE_OP -Returns the total number of waiters that were woken up. -This is the sum of the woken waiters on the two futexes for -the futex words at -.I uaddr -and -.IR uaddr2 . -.TP .B FUTEX_WAIT_BITSET Returns 0 if the caller was woken up. See @@ -1235,8 +1079,7 @@ equals (i.e., an attempt was made to requeue to the same futex). .TP .B EINVAL -.RB ( FUTEX_WAKE_OP , -.BR FUTEX_WAKE_BITSET ) +.RB ( FUTEX_WAKE_BITSET ) The kernel detected an inconsistency between the user-space state at .I uaddr and the kernel state\[em]that is, it detected a waiter which waits in diff --git a/man/man2const/FUTEX_WAKE_OP.2const b/man/man2const/FUTEX_WAKE_OP.2const new file mode 100644 index 000000000..9b88574e9 --- /dev/null +++ b/man/man2const/FUTEX_WAKE_OP.2const @@ -0,0 +1,213 @@ +.\" Copyright, the authors of the Linux man-pages project +.\" +.\" %%%LICENSE_START(FREELY_REDISTRIBUTABLE) +.\" may be freely modified and distributed +.\" %%%LICENSE_END +.\" +.TH FUTEX_WAKE_OP 2const (date) "Linux man-pages (unreleased)" +.SH NAME +FUTEX_WAKE_OP \- fast user-space locking +.SH LIBRARY +Standard C library +.RI ( libc ,\~ \-lc ) +.SH SYNOPSIS +.nf +.BR "#include " " /* Definition of " FUTEX_* " constants */" +.BR "#include " " /* Definition of " SYS_* " constants */" +.B #include +.P +.BI "long syscall(SYS_futex, uint32_t *" uaddr ", FUTEX_WAKE_OP, uint32_t " val , +.BI " uint32_t " val2 ", uint32_t *" uaddr2 , +.BI " uint32_t " val3 ); +.fi +.SH DESCRIPTION +.TP +.BR FUTEX_WAKE_OP " (since Linux 2.6.14)" +.\" commit 4732efbeb997189d9f9b04708dc26bf8613ed721 +.\" Author: Jakub Jelinek +.\" Date: Tue Sep 6 15:16:25 2005 -0700 +.\" FIXME. (Torvald) The glibc condvar implementation is currently being +.\" revised (e.g., to not use an internal lock anymore). +.\" It is probably more future-proof to remove this paragraph. +.\" [Torvald, do you have an update here?] +This operation was added to support some user-space use cases +where more than one futex must be handled at the same time. +The most notable example is the implementation of +.BR pthread_cond_signal (3), +which requires operations on two futexes, +the one used to implement the mutex and the one used in the implementation +of the wait queue associated with the condition variable. +.B FUTEX_WAKE_OP +allows such cases to be implemented without leading to +high rates of contention and context switching. +.IP +The +.B FUTEX_WAKE_OP +operation is equivalent to executing the following code atomically +and totally ordered with respect to other futex operations on +any of the two supplied futex words: +.IP +.in +4n +.EX +uint32_t oldval = *(uint32_t *) uaddr2; +*(uint32_t *) uaddr2 = oldval \f[I]op\f[] \f[I]oparg\f[]; +futex(uaddr, FUTEX_WAKE, val, 0, 0, 0); +if (oldval \f[I]cmp\f[] \f[I]cmparg\f[]) + futex(uaddr2, FUTEX_WAKE, val2, 0, 0, 0); +.EE +.in +.IP +In other words, +.B FUTEX_WAKE_OP +does the following: +.RS +.IP \[bu] 3 +saves the original value of the futex word at +.I uaddr2 +and performs an operation to modify the value of the futex at +.IR uaddr2 ; +this is an atomic read-modify-write memory access (i.e., using atomic +machine instructions of the respective architecture) +.IP \[bu] +wakes up a maximum of +.I val +waiters on the futex for the futex word at +.IR uaddr ; +and +.IP \[bu] +dependent on the results of a test of the original value of the +futex word at +.IR uaddr2 , +wakes up a maximum of +.I val2 +waiters on the futex for the futex word at +.IR uaddr2 . +.RE +.IP +The operation and comparison that are to be performed are encoded +in the bits of the argument +.IR val3 . +Pictorially, the encoding is: +.IP +.in +4n +.EX ++---+---+-----------+-----------+ +|op |cmp| oparg | cmparg | ++---+---+-----------+-----------+ + 4 4 12 12 <== # of bits +.EE +.in +.IP +Expressed in code, the encoding is: +.IP +.in +4n +.EX +#define FUTEX_OP(op, oparg, cmp, cmparg) \[rs] + (((op & 0xf) << 28) | \[rs] + ((cmp & 0xf) << 24) | \[rs] + ((oparg & 0xfff) << 12) | \[rs] + (cmparg & 0xfff)) +.EE +.in +.IP +In the above, +.I op +and +.I cmp +are each one of the codes listed below. +The +.I oparg +and +.I cmparg +components are literal numeric values, except as noted below. +.IP +The +.I op +component has one of the following values: +.IP +.in +4n +.EX +FUTEX_OP_SET 0 /* uaddr2 = oparg; */ +FUTEX_OP_ADD 1 /* uaddr2 += oparg; */ +FUTEX_OP_OR 2 /* uaddr2 |= oparg; */ +FUTEX_OP_ANDN 3 /* uaddr2 &= \[ti]oparg; */ +FUTEX_OP_XOR 4 /* uaddr2 \[ha]= oparg; */ +.EE +.in +.IP +In addition, bitwise ORing the following value into +.I op +causes +.I (1\~<<\~oparg) +to be used as the operand: +.IP +.in +4n +.EX +FUTEX_OP_ARG_SHIFT 8 /* Use (1 << oparg) as operand */ +.EE +.in +.IP +The +.I cmp +field is one of the following: +.IP +.in +4n +.EX +FUTEX_OP_CMP_EQ 0 /* if (oldval == cmparg) wake */ +FUTEX_OP_CMP_NE 1 /* if (oldval != cmparg) wake */ +FUTEX_OP_CMP_LT 2 /* if (oldval < cmparg) wake */ +FUTEX_OP_CMP_LE 3 /* if (oldval <= cmparg) wake */ +FUTEX_OP_CMP_GT 4 /* if (oldval > cmparg) wake */ +FUTEX_OP_CMP_GE 5 /* if (oldval >= cmparg) wake */ +.EE +.in +.IP +The return value of +.B FUTEX_WAKE_OP +is the sum of the number of waiters woken on the futex +.I uaddr +plus the number of waiters woken on the futex +.IR uaddr2 . +.\" +.SH RETURN VALUE +On error, +\-1 is returned, +and +.I errno +is set to indicate the error. +.P +On success, +.B FUTEX_WAKE_OP +Returns the total number of waiters that were woken up. +This is the sum of the woken waiters on the two futexes for +the futex words at +.I uaddr +and +.IR uaddr2 . +.SH ERRORS +See +.BR futex (2). +.TP +.B EFAULT +.I uaddr2 +did not point to a valid user-space address. +.TP +.B EINVAL +.I uaddr2 +does not point to a valid object\[em]that is, +the address is not four-byte-aligned. +.TP +.B EINVAL +The kernel detected an inconsistency between the user-space state at +.I uaddr +and the kernel state\[em]that is, it detected a waiter which waits in +.B FUTEX_LOCK_PI +or +.B FUTEX_LOCK_PI2 +on +.IR uaddr . +.SH STANDARDS +Linux. +.SH HISTORY +.SH SEE ALSO +.BR futex (2)