Source-Changes-HG archive

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

[src/trunk]: src/sys/kern Make sure futex waits never return ERESTART.



details:   https://anonhg.NetBSD.org/src/rev/3be01ab41970
branches:  trunk
changeset: 971742:3be01ab41970
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Sun May 03 01:26:39 2020 +0000

description:
Make sure futex waits never return ERESTART.

If the user had passed in a relative timeout, this would have the
effect of waiting for the full relative time repeatedly, without
regard for how much time had elapsed during the wait before a signal.

In principle this may not be necessary for absolute timeouts or
indefinite timeouts, but it's not clear there's an advantage; we do
the same for various other syscalls like nanosleep.

Perhaps in the future we can arrange to keep the state of how much
time had elapsed when we restart like Linux does, but that's a much
more ambitious change.

diffstat:

 sys/kern/sys_futex.c |  10 +++++++---
 1 files changed, 7 insertions(+), 3 deletions(-)

diffs (36 lines):

diff -r a82e0439d319 -r 3be01ab41970 sys/kern/sys_futex.c
--- a/sys/kern/sys_futex.c      Sun May 03 01:25:48 2020 +0000
+++ b/sys/kern/sys_futex.c      Sun May 03 01:26:39 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sys_futex.c,v 1.8 2020/05/03 01:25:48 riastradh Exp $  */
+/*     $NetBSD: sys_futex.c,v 1.9 2020/05/03 01:26:39 riastradh 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.8 2020/05/03 01:25:48 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_futex.c,v 1.9 2020/05/03 01:26:39 riastradh Exp $");
 
 /*
  * Futexes
@@ -954,12 +954,16 @@
         * If we were woken up, the waker will have removed fw from the
         * queue.  But if anything went wrong, we must remove fw from
         * the queue ourselves.  While here, convert EWOULDBLOCK to
-        * ETIMEDOUT.
+        * ETIMEDOUT in case cv_timedwait_sig returned EWOULDBLOCK, and
+        * convert ERESTART to EINTR so that we don't restart with the
+        * same relative timeout after time has elapsed.
         */
        if (error) {
                futex_wait_abort(fw);
                if (error == EWOULDBLOCK)
                        error = ETIMEDOUT;
+               else if (error == ERESTART)
+                       error = EINTR;
        }
 
        mutex_exit(&fw->fw_lock);



Home | Main Index | Thread Index | Old Index