Module Name: src Committed By: riastradh Date: Tue May 5 15:25:18 UTC 2020
Modified Files: src/sys/kern: sys_futex.c src/sys/sys: futex.h Log Message: Revert "Use cv_timedwaitclock_sig in futex." Turned out to break things; we'll do this another way. To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.11 src/sys/kern/sys_futex.c cvs rdiff -u -r1.3 -r1.4 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.10 src/sys/kern/sys_futex.c:1.11 --- src/sys/kern/sys_futex.c:1.10 Tue May 5 15:23:32 2020 +++ src/sys/kern/sys_futex.c Tue May 5 15:25:18 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: sys_futex.c,v 1.10 2020/05/05 15:23:32 riastradh Exp $ */ +/* $NetBSD: sys_futex.c,v 1.11 2020/05/05 15:25:18 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.10 2020/05/05 15:23:32 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sys_futex.c,v 1.11 2020/05/05 15:25:18 riastradh Exp $"); /* * Futexes @@ -916,18 +916,17 @@ futex_wait_abort(struct futex_wait *fw) } /* - * futex_wait(fw, timeout, clkid, clkflags) + * futex_wait(fw, deadline, clkid) * - * 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. + * 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. */ static int -futex_wait(struct futex_wait *fw, struct timespec *timeout, clockid_t clkid, - int clkflags) +futex_wait(struct futex_wait *fw, const struct timespec *deadline, + clockid_t clkid) { int error = 0; @@ -935,7 +934,7 @@ futex_wait(struct futex_wait *fw, struct mutex_enter(&fw->fw_lock); for (;;) { - /* If we're done already, stop and report success. */ + /* If we're done yet, stop and report success. */ if (fw->fw_bitset == 0 || fw->fw_futex == NULL) { error = 0; break; @@ -946,8 +945,30 @@ futex_wait(struct futex_wait *fw, struct break; /* Not done yet. Wait. */ - error = cv_timedwaitclock_sig(&fw->fw_cv, &fw->fw_lock, - timeout, clkid, clkflags, DEFAULT_TIMEOUT_EPSILON); + 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); + } } /* @@ -1167,11 +1188,13 @@ futex_queue_unlock2(struct futex *f, str */ static int futex_func_wait(bool shared, int *uaddr, int val, int val3, - struct timespec *timeout, clockid_t clkid, int clkflags, + const 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; /* @@ -1185,6 +1208,17 @@ 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) @@ -1221,7 +1255,7 @@ futex_func_wait(bool shared, int *uaddr, f = NULL; /* Wait. */ - error = futex_wait(fw, timeout, clkid, clkflags); + error = futex_wait(fw, deadline, clkid); if (error) goto out; @@ -1546,8 +1580,8 @@ out: * parsed out. */ int -do_futex(int *uaddr, int op, int val, struct timespec *timeout, int *uaddr2, - int val2, int val3, register_t *retval) +do_futex(int *uaddr, int op, int val, const 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.3 src/sys/sys/futex.h:1.4 --- src/sys/sys/futex.h:1.3 Sun May 3 01:25:48 2020 +++ src/sys/sys/futex.h Tue May 5 15:25:18 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: futex.h,v 1.3 2020/05/03 01:25:48 riastradh Exp $ */ +/* $NetBSD: futex.h,v 1.4 2020/05/05 15:25:18 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, struct timespec *, int *, int, int, - register_t *); +int do_futex(int *, int, int, const struct timespec *, int *, int, + int, register_t *); void futex_sys_init(void); void futex_sys_fini(void); #endif /* _KERNEL */