Module Name:    src
Committed By:   riastradh
Date:           Sun May  3 01:26:39 UTC 2020

Modified Files:
        src/sys/kern: sys_futex.c

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.9 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.8 src/sys/kern/sys_futex.c:1.9
--- src/sys/kern/sys_futex.c:1.8	Sun May  3 01:25:48 2020
+++ src/sys/kern/sys_futex.c	Sun May  3 01:26:39 2020
@@ -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 @@ futex_wait(struct futex_wait *fw, struct
 	 * 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);

Reply via email to