Module Name: src Committed By: thorpej Date: Sat Aug 7 01:22:34 UTC 2021
Modified Files: src/sys/kern [thorpej-futex2]: sys_futex.c Log Message: The return values for FUTEX_REQUEUE and FUTEX_CMP_REQUEUE are different, but we weren't doing to the right thing. FUTEX_REQUEUE returns the number of waiters awakened. FUTEX_CMP_REQUEUE returns the number of waiters awakenend plus the number of waiters requeued (and it is an exercise for the caller to calculate the number requeued, if it cares). To generate a diff of this commit: cvs rdiff -u -r1.12.4.4 -r1.12.4.5 src/sys/kern/sys_futex.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/sys_futex.c diff -u src/sys/kern/sys_futex.c:1.12.4.4 src/sys/kern/sys_futex.c:1.12.4.5 --- src/sys/kern/sys_futex.c:1.12.4.4 Fri Aug 6 23:53:53 2021 +++ src/sys/kern/sys_futex.c Sat Aug 7 01:22:33 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: sys_futex.c,v 1.12.4.4 2021/08/06 23:53:53 thorpej Exp $ */ +/* $NetBSD: sys_futex.c,v 1.12.4.5 2021/08/07 01:22:33 thorpej Exp $ */ /*- * Copyright (c) 2018, 2019, 2020 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sys_futex.c,v 1.12.4.4 2021/08/06 23:53:53 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sys_futex.c,v 1.12.4.5 2021/08/07 01:22:33 thorpej Exp $"); /* * Futexes @@ -1158,7 +1158,7 @@ futex_wait(struct futex *f, int q, const static unsigned futex_wake(struct futex *f, int q, unsigned int const nwake, struct futex *f2, int q2, unsigned int const nrequeue, - int bitset) + int bitset, unsigned int *nrequeuedp) { struct lwp *l, *l_next; unsigned nwoken = 0; @@ -1234,7 +1234,10 @@ futex_wake(struct futex *f, int q, unsig futex_sq_unlock2(f, f2); /* Return the number of waiters woken and requeued. */ - return nwoken + nrequeued; + if (nrequeuedp != NULL) { + *nrequeuedp = nrequeued; + } + return nwoken; } /* @@ -1473,7 +1476,7 @@ futex_func_wake(bool shared, int *uaddr, */ futex_op_lock(f); nwoken = futex_wake(f, FUTEX_WRITERQ, val, - NULL, FUTEX_WRITERQ, 0, val3); + NULL, FUTEX_WRITERQ, 0, val3, NULL); futex_op_unlock(f); /* Release the futex. */ @@ -1498,6 +1501,7 @@ futex_func_requeue(bool shared, int op, { struct futex *f = NULL, *f2 = NULL; unsigned nwoken = 0; /* default to zero woken on early return */ + unsigned nrequeued = 0; int error; /* Reject negative number of wakeups or requeues. */ @@ -1534,13 +1538,19 @@ futex_func_requeue(bool shared, int op, error = 0; nwoken = futex_wake(f, FUTEX_WRITERQ, val, f2, FUTEX_WRITERQ, val2, - FUTEX_BITSET_MATCH_ANY); + FUTEX_BITSET_MATCH_ANY, + &nrequeued); } futex_op_unlock2(f, f2); out: - /* Return the number of waiters woken. */ - *retval = nwoken; + /* + * For FUTUEX_REQUEUE, return the numner of waiters woken. + * + * For FUTEX_CMP_REQUEUE, return the number of waiters woken + * **and** requeued. + */ + *retval = nwoken + (op == FUTEX_CMP_REQUEUE) ? nrequeued : 0; /* Release the futexes if we got them. */ if (f2) @@ -1728,11 +1738,11 @@ futex_func_wake_op(bool shared, int *uad } while (actual != oldval); nwoken = (f ? futex_wake(f, FUTEX_WRITERQ, val, NULL, FUTEX_WRITERQ, 0, - FUTEX_BITSET_MATCH_ANY) : 0); + FUTEX_BITSET_MATCH_ANY, NULL) : 0); if (f2 && futex_compute_cmp(oldval, val3)) nwoken += futex_wake(f2, FUTEX_WRITERQ, val2, NULL, FUTEX_WRITERQ, 0, - FUTEX_BITSET_MATCH_ANY); + FUTEX_BITSET_MATCH_ANY, NULL); /* Success! */ error = 0; @@ -2067,7 +2077,7 @@ release_futex(uintptr_t const uptr, lwpi if (oldval & FUTEX_WAITERS) { (void)futex_wake(f, FUTEX_WRITERQ, 1, NULL, FUTEX_WRITERQ, 0, - FUTEX_BITSET_MATCH_ANY); + FUTEX_BITSET_MATCH_ANY, NULL); } /* Unlock the queue and release the futex. */