Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/thorpej-futex2]: src/sys/kern The return values for FUTEX_REQUEUE and FU...



details:   https://anonhg.NetBSD.org/src/rev/bda2084ea55f
branches:  thorpej-futex2
changeset: 1022749:bda2084ea55f
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Sat Aug 07 01:22:33 2021 +0000

description:
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).

diffstat:

 sys/kern/sys_futex.c |  32 +++++++++++++++++++++-----------
 1 files changed, 21 insertions(+), 11 deletions(-)

diffs (102 lines):

diff -r 7b2c7abe0730 -r bda2084ea55f sys/kern/sys_futex.c
--- a/sys/kern/sys_futex.c      Fri Aug 06 23:53:53 2021 +0000
+++ b/sys/kern/sys_futex.c      Sat Aug 07 01:22:33 2021 +0000
@@ -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 @@
 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_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_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 @@
 {
        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 @@
                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 @@
        } 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 @@
        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.  */



Home | Main Index | Thread Index | Old Index