Module Name: src
Committed By: riastradh
Date: Sun May 3 01:25:48 UTC 2020
Modified Files:
src/sys/kern: sys_futex.c
src/sys/sys: futex.h
Log Message:
Use cv_timedwaitclock_sig in futex.
Possible fix for hangs observed with Java under Linux emulation.
To generate a diff of this commit:
cvs rdiff -u -r1.7 -r1.8 src/sys/kern/sys_futex.c
cvs rdiff -u -r1.2 -r1.3 src/sys/sys/futex.h
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.7 src/sys/kern/sys_futex.c:1.8
--- src/sys/kern/sys_futex.c:1.7 Tue Apr 28 17:27:03 2020
+++ src/sys/kern/sys_futex.c Sun May 3 01:25:48 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: sys_futex.c,v 1.7 2020/04/28 17:27:03 riastradh Exp $ */
+/* $NetBSD: sys_futex.c,v 1.8 2020/05/03 01:25:48 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.7 2020/04/28 17:27:03 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_futex.c,v 1.8 2020/05/03 01:25:48 riastradh Exp $");
/*
* Futexes
@@ -916,17 +916,18 @@ futex_wait_abort(struct futex_wait *fw)
}
/*
- * futex_wait(fw, deadline, clkid)
+ * futex_wait(fw, timeout, clkid, clkflags)
*
- * fw must be a waiter on a futex's queue. Wait until deadline on
- * the clock clkid, or forever if deadline is NULL, for a futex
- * wakeup. Return 0 on explicit wakeup or destruction of futex,
- * ETIMEDOUT on timeout, EINTR/ERESTART on signal. Either way, fw
- * will no longer be on a futex queue on return.
+ * fw must be a waiter on a futex's queue. Wait for timeout on
+ * the clock clkid according to clkflags (TIMER_*), or forever if
+ * timeout is NULL, for a futex wakeup. Return 0 on explicit
+ * wakeup or destruction of futex, ETIMEDOUT on timeout,
+ * EINTR/ERESTART on signal. Either way, fw will no longer be on
+ * a futex queue on return.
*/
static int
-futex_wait(struct futex_wait *fw, const struct timespec *deadline,
- clockid_t clkid)
+futex_wait(struct futex_wait *fw, struct timespec *timeout, clockid_t clkid,
+ int clkflags)
{
int error = 0;
@@ -934,7 +935,7 @@ futex_wait(struct futex_wait *fw, const
mutex_enter(&fw->fw_lock);
for (;;) {
- /* If we're done yet, stop and report success. */
+ /* If we're done already, stop and report success. */
if (fw->fw_bitset == 0 || fw->fw_futex == NULL) {
error = 0;
break;
@@ -945,30 +946,8 @@ futex_wait(struct futex_wait *fw, const
break;
/* Not done yet. Wait. */
- if (deadline) {
- struct timespec ts;
-
- /* Check our watch. */
- error = clock_gettime1(clkid, &ts);
- if (error)
- break;
-
- /* If we're past the deadline, ETIMEDOUT. */
- if (timespeccmp(deadline, &ts, <=)) {
- error = ETIMEDOUT;
- break;
- }
-
- /* Count how much time is left. */
- timespecsub(deadline, &ts, &ts);
-
- /* Wait for that much time, allowing signals. */
- error = cv_timedwait_sig(&fw->fw_cv, &fw->fw_lock,
- tstohz(&ts));
- } else {
- /* Wait indefinitely, allowing signals. */
- error = cv_wait_sig(&fw->fw_cv, &fw->fw_lock);
- }
+ error = cv_timedwaitclock_sig(&fw->fw_cv, &fw->fw_lock,
+ timeout, clkid, clkflags, DEFAULT_TIMEOUT_EPSILON);
}
/*
@@ -1188,13 +1167,11 @@ futex_queue_unlock2(struct futex *f, str
*/
static int
futex_func_wait(bool shared, int *uaddr, int val, int val3,
- const struct timespec *timeout, clockid_t clkid, int clkflags,
+ struct timespec *timeout, clockid_t clkid, int clkflags,
register_t *retval)
{
struct futex *f;
struct futex_wait wait, *fw = &wait;
- struct timespec ts;
- const struct timespec *deadline;
int error;
/*
@@ -1208,17 +1185,6 @@ futex_func_wait(bool shared, int *uaddr,
if (!futex_test(uaddr, val))
return EAGAIN;
- /* Determine a deadline on the specified clock. */
- if (timeout == NULL || (clkflags & TIMER_ABSTIME) == TIMER_ABSTIME) {
- deadline = timeout;
- } else {
- error = clock_gettime1(clkid, &ts);
- if (error)
- return error;
- timespecadd(&ts, timeout, &ts);
- deadline = &ts;
- }
-
/* Get the futex, creating it if necessary. */
error = futex_lookup_create(uaddr, shared, &f);
if (error)
@@ -1255,7 +1221,7 @@ futex_func_wait(bool shared, int *uaddr,
f = NULL;
/* Wait. */
- error = futex_wait(fw, deadline, clkid);
+ error = futex_wait(fw, timeout, clkid, clkflags);
if (error)
goto out;
@@ -1580,8 +1546,8 @@ out:
* parsed out.
*/
int
-do_futex(int *uaddr, int op, int val, const struct timespec *timeout,
- int *uaddr2, int val2, int val3, register_t *retval)
+do_futex(int *uaddr, int op, int val, struct timespec *timeout, int *uaddr2,
+ int val2, int val3, register_t *retval)
{
const bool shared = (op & FUTEX_PRIVATE_FLAG) ? false : true;
const clockid_t clkid = (op & FUTEX_CLOCK_REALTIME) ? CLOCK_REALTIME
Index: src/sys/sys/futex.h
diff -u src/sys/sys/futex.h:1.2 src/sys/sys/futex.h:1.3
--- src/sys/sys/futex.h:1.2 Mon Apr 27 02:54:42 2020
+++ src/sys/sys/futex.h Sun May 3 01:25:48 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: futex.h,v 1.2 2020/04/27 02:54:42 rin Exp $ */
+/* $NetBSD: futex.h,v 1.3 2020/05/03 01:25:48 riastradh Exp $ */
/*-
* Copyright (c) 2018, 2019 The NetBSD Foundation, Inc.
@@ -175,8 +175,8 @@ struct lwp;
int futex_robust_head_lookup(struct lwp *, lwpid_t, void **);
void futex_release_all_lwp(struct lwp *, lwpid_t);
-int do_futex(int *, int, int, const struct timespec *, int *, int,
- int, register_t *);
+int do_futex(int *, int, int, struct timespec *, int *, int, int,
+ register_t *);
void futex_sys_init(void);
void futex_sys_fini(void);
#endif /* _KERNEL */