Index: arch/acorn32/mainbus/fd.c =================================================================== RCS file: /cvsroot/src/sys/arch/acorn32/mainbus/fd.c,v retrieving revision 1.38 diff -u -p -r1.38 fd.c --- arch/acorn32/mainbus/fd.c 28 Apr 2008 20:23:10 -0000 1.38 +++ arch/acorn32/mainbus/fd.c 7 May 2008 13:34:07 -0000 @@ -1536,7 +1536,7 @@ fdformat(dev, finfo, l) /* XXX very dodgy */ mutex_enter(bp->b_objlock); while (!(bp->b_oflags & BO_DONE)) { - rv = cv_timedwait(&bp->b_done, bp->b_objlock, 20 * hz); + rv = cv_timedwait(&bp->b_done, bp->b_objlock, cv_time_sec(20)); if (rv == EWOULDBLOCK) break; } Index: arch/atari/dev/hdfd.c =================================================================== RCS file: /cvsroot/src/sys/arch/atari/dev/hdfd.c,v retrieving revision 1.61 diff -u -p -r1.61 hdfd.c --- arch/atari/dev/hdfd.c 3 Jan 2008 16:06:24 -0000 1.61 +++ arch/atari/dev/hdfd.c 7 May 2008 13:34:09 -0000 @@ -1560,7 +1560,7 @@ fdformat(dev, finfo, p) /* ...and wait for it to complete */ mutex_enter(bp->b_objlock); while(!(bp->b_oflags & BO_DONE)) { - rv = cv_timedwait(&bp->b_done, bp->b_objlock, 20 * hz); + rv = cv_timedwait(&bp->b_done, bp->b_objlock, cv_time_sec(20)); if (rv == EWOULDBLOCK) break; } Index: arch/sun3/dev/fd.c =================================================================== RCS file: /cvsroot/src/sys/arch/sun3/dev/fd.c,v retrieving revision 1.62 diff -u -p -r1.62 fd.c --- arch/sun3/dev/fd.c 4 Jan 2008 19:45:54 -0000 1.62 +++ arch/sun3/dev/fd.c 7 May 2008 13:34:15 -0000 @@ -1804,7 +1804,7 @@ fdformat(dev_t dev, struct ne7_fd_formb /* XXX dodgy */ mutex_enter(bp->b_objlock); while (!(bp->b_oflags & BO_DONE)) { - rv = cv_timedwait(&bp->b_done, bp->b_objlock, 20 * hz); + rv = cv_timedwait(&bp->b_done, bp->b_objlock, cv_time_sec(20)); if (rv == EWOULDBLOCK) break; } Index: compat/linux/common/linux_futex.c =================================================================== RCS file: /cvsroot/src/sys/compat/linux/common/linux_futex.c,v retrieving revision 1.13 diff -u -p -r1.13 linux_futex.c --- compat/linux/common/linux_futex.c 30 Apr 2008 14:07:13 -0000 1.13 +++ compat/linux/common/linux_futex.c 7 May 2008 13:34:16 -0000 @@ -80,7 +80,7 @@ static kmutex_t *futex_lock = NULL; static struct futex *futex_get(void *); static void futex_put(struct futex *); -static int futex_sleep(struct futex *, unsigned int); +static int futex_sleep(struct futex *, clock_t); static int futex_wake(struct futex *, int, struct futex *); int @@ -100,8 +100,8 @@ linux_sys_futex(struct lwp *l, const str int error = 0; struct futex *f; struct futex *newf; - int timeout_hz = 0; kmutex_t *lock; + clock_t timo; /* First time use */ if (__predict_false(futex_lock == NULL)) { @@ -126,15 +126,13 @@ linux_sys_futex(struct lwp *l, const str if (val != SCARG(uap, val)) return EWOULDBLOCK; + timo = 0; if (SCARG(uap, timeout) != NULL) { if ((error = copyin(SCARG(uap, timeout), &timeout, sizeof(timeout))) != 0) return error; - error = itimespecfix(&timeout); - if (error) - return error; - timeout_hz = tstohz(&timeout); - } + timo = cv_time_spec(&timeout, false); + } FUTEXPRINTF(("FUTEX_WAIT %d.%d: val = %d, uaddr = %p, " "*uaddr = %d, timeout = %lld.%09ld\n", @@ -143,7 +141,7 @@ linux_sys_futex(struct lwp *l, const str timeout.tv_nsec)); f = futex_get(SCARG(uap, uaddr)); - ret = futex_sleep(f, timeout_hz); + ret = futex_sleep(f, timo); futex_put(f); FUTEXPRINTF(("FUTEX_WAIT %d.%d: uaddr = %p, " @@ -265,7 +263,7 @@ futex_put(struct futex *f) } static int -futex_sleep(struct futex *f, unsigned int timeout) +futex_sleep(struct futex *f, clock_t timo) { struct waiting_proc *wp; int ret; @@ -275,12 +273,12 @@ futex_sleep(struct futex *f, unsigned in FUTEX_LOCK; TAILQ_INSERT_TAIL(&f->f_waiting_proc, wp, wp_list); - ret = cv_timedwait_sig(&wp->wp_futex_cv, futex_lock, timeout); + ret = cv_timedwait_sig(&wp->wp_futex_cv, futex_lock, timo); TAILQ_REMOVE(&f->f_waiting_proc, wp, wp_list); FUTEX_UNLOCK; if ((ret == 0) && (wp->wp_new_futex != NULL)) { - ret = futex_sleep(wp->wp_new_futex, timeout); + ret = futex_sleep(wp->wp_new_futex, timo); futex_put(wp->wp_new_futex); /* futex_get called in wakeup */ } Index: dev/acpi/acpi_ec.c =================================================================== RCS file: /cvsroot/src/sys/dev/acpi/acpi_ec.c,v retrieving revision 1.51 diff -u -p -r1.51 acpi_ec.c --- dev/acpi/acpi_ec.c 29 Feb 2008 06:35:40 -0000 1.51 +++ dev/acpi/acpi_ec.c 7 May 2008 13:34:19 -0000 @@ -582,7 +582,8 @@ acpiec_read(device_t dv, uint8_t addr, u sc->sc_state); return AE_ERROR; } - } else while (cv_timedwait(&sc->sc_cv, &sc->sc_mtx, EC_CMD_TIMEOUT * hz)) { + } else while (cv_timedwait(&sc->sc_cv, &sc->sc_mtx, + cv_time_tick(EC_CMD_TIMEOUT))) { mutex_exit(&sc->sc_mtx); AcpiClearGpe(sc->sc_gpeh, sc->sc_gpebit, ACPI_NOT_ISR); acpiec_unlock(dv); @@ -631,7 +632,8 @@ acpiec_write(device_t dv, uint8_t addr, sc->sc_state); return AE_ERROR; } - } else while (cv_timedwait(&sc->sc_cv, &sc->sc_mtx, EC_CMD_TIMEOUT * hz)) { + } else while (cv_timedwait(&sc->sc_cv, &sc->sc_mtx, + cv_time_tick(EC_CMD_TIMEOUT))) { mutex_exit(&sc->sc_mtx); AcpiClearGpe(sc->sc_gpeh, sc->sc_gpebit, ACPI_NOT_ISR); acpiec_unlock(dv); Index: dev/acpi/acpica/OsdSchedule.c =================================================================== RCS file: /cvsroot/src/sys/dev/acpi/acpica/OsdSchedule.c,v retrieving revision 1.7 diff -u -p -r1.7 OsdSchedule.c --- dev/acpi/acpica/OsdSchedule.c 24 Apr 2008 21:42:05 -0000 1.7 +++ dev/acpi/acpica/OsdSchedule.c 7 May 2008 13:34:19 -0000 @@ -165,7 +165,7 @@ AcpiOsSleep(ACPI_INTEGER Milliseconds) mutex_enter(&acpi_osd_sleep_mtx); cv_timedwait_sig(&acpi_osd_sleep_cv, &acpi_osd_sleep_mtx, - MAX(mstohz(Milliseconds), 1)); + cv_time_ms(MAX(mstohz(Milliseconds), 1))); mutex_exit(&acpi_osd_sleep_mtx); } Index: dev/acpi/acpica/OsdSynch.c =================================================================== RCS file: /cvsroot/src/sys/dev/acpi/acpica/OsdSynch.c,v retrieving revision 1.10 diff -u -p -r1.10 OsdSynch.c --- dev/acpi/acpica/OsdSynch.c 15 Dec 2007 00:39:25 -0000 1.10 +++ dev/acpi/acpica/OsdSynch.c 7 May 2008 13:34:19 -0000 @@ -169,7 +169,8 @@ AcpiOsWaitSemaphore(ACPI_SEMAPHORE Handl { struct acpi_semaphore *as = (void *) Handle; ACPI_STATUS rv; - int timo, error; + int error, timo; + clock_t when; /* * This implementation has a bug: It has to stall for the entire @@ -186,12 +187,13 @@ AcpiOsWaitSemaphore(ACPI_SEMAPHORE Handl /* A timeout of 0xFFFF means "forever". */ if (Timeout == 0xFFFF) - timo = 0; + when = 0; else { /* Compute the timeout using uSec per tick. */ timo = (Timeout * 1000) / (1000000 / hz); if (timo <= 0) timo = 1; + when = cv_time_tick(timo); } mutex_enter(&as->as_slock); @@ -210,7 +212,7 @@ AcpiOsWaitSemaphore(ACPI_SEMAPHORE Handl ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "semaphore blocked, sleeping %d ticks\n", timo)); - error = cv_timedwait(&as->as_cv, &as->as_slock, timo); + error = cv_timedwait(&as->as_cv, &as->as_slock, when); if (error == EWOULDBLOCK) { rv = AE_TIME; break; Index: dev/bluetooth/btsco.c =================================================================== RCS file: /cvsroot/src/sys/dev/bluetooth/btsco.c,v retrieving revision 1.20 diff -u -p -r1.20 btsco.c --- dev/bluetooth/btsco.c 24 Apr 2008 11:38:36 -0000 1.20 +++ dev/bluetooth/btsco.c 7 May 2008 13:34:20 -0000 @@ -560,7 +560,8 @@ btsco_open(void *hdl, int flags) { struct sockaddr_bt sa; struct btsco_softc *sc = hdl; - int err, timo; + clock_t timo; + int err; DPRINTF("%s flags 0x%x\n", sc->sc_name, flags); /* flags FREAD & FWRITE? */ @@ -611,7 +612,7 @@ btsco_open(void *hdl, int flags) goto done; } - timo = BTSCO_TIMEOUT; + timo = cv_time_tick(BTSCO_TIMEOUT); } sc->sc_state = BTSCO_WAIT_CONNECT; Index: dev/i2o/iop.c =================================================================== RCS file: /cvsroot/src/sys/dev/i2o/iop.c,v retrieving revision 1.71 diff -u -p -r1.71 iop.c --- dev/i2o/iop.c 5 May 2008 17:11:16 -0000 1.71 +++ dev/i2o/iop.c 7 May 2008 13:34:20 -0000 @@ -1,7 +1,7 @@ /* $NetBSD: iop.c,v 1.71 2008/05/05 17:11:16 ad Exp $ */ /*- - * Copyright (c) 2000, 2001, 2002, 2007 The NetBSD Foundation, Inc. + * Copyright (c) 2000, 2001, 2002, 2007, 2008 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -630,7 +630,8 @@ iop_reconf_thread(void *cookie) iop_reconfigure(sc, le32toh(lct.changeindicator)); chgind = sc->sc_chgind + 1; } - (void)cv_timedwait(&sc->sc_confcv, &sc->sc_conflock, hz * 5); + (void)cv_timedwait(&sc->sc_confcv, &sc->sc_conflock, + cv_time_sec(5)); mutex_exit(&sc->sc_conflock); } } @@ -2240,7 +2241,7 @@ iop_msg_wait(struct iop_softc *sc, struc mutex_spin_exit(&sc->sc_intrlock); return; } - rv = cv_timedwait(&im->im_cv, &sc->sc_intrlock, mstohz(timo)); + rv = cv_timedwait(&im->im_cv, &sc->sc_intrlock, cv_time_ms(timo)); mutex_spin_exit(&sc->sc_intrlock); #ifdef I2ODEBUG Index: dev/i2o/ld_iop.c =================================================================== RCS file: /cvsroot/src/sys/dev/i2o/ld_iop.c,v retrieving revision 1.28 diff -u -p -r1.28 ld_iop.c --- dev/i2o/ld_iop.c 28 Apr 2008 20:23:48 -0000 1.28 +++ dev/i2o/ld_iop.c 7 May 2008 13:34:21 -0000 @@ -1,7 +1,7 @@ /* $NetBSD: ld_iop.c,v 1.28 2008/04/28 20:23:48 martin Exp $ */ /*- - * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc. + * Copyright (c) 2000, 2001, 2008 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -307,9 +307,10 @@ ld_iop_unconfig(struct ld_iop_softc *sc, I2O_EVENT_GEN_EVENT_MASK_MODIFIED); mutex_spin_enter(&iop->sc_intrlock); - if ((sc->sc_flags & LD_IOP_NEW_EVTMASK) == 0) + if ((sc->sc_flags & LD_IOP_NEW_EVTMASK) == 0) { cv_timedwait(&sc->sc_eventii.ii_cv, - &iop->sc_intrlock, hz * 5); + &iop->sc_intrlock, cv_time_sec(5)); + } mutex_spin_exit(&iop->sc_intrlock); } Index: dev/ic/pcf8584.c =================================================================== RCS file: /cvsroot/src/sys/dev/ic/pcf8584.c,v retrieving revision 1.5 diff -u -p -r1.5 pcf8584.c --- dev/ic/pcf8584.c 28 Apr 2008 20:23:51 -0000 1.5 +++ dev/ic/pcf8584.c 7 May 2008 13:34:21 -0000 @@ -84,7 +84,8 @@ pcf8584_wait(struct pcf8584_handle *ha, } } else { mutex_enter(&ha->ha_intrmtx); - cv_timedwait(&ha->ha_intrcond, &ha->ha_intrmtx, mstohz(20)); + (void)cv_timedwait(&ha->ha_intrcond, &ha->ha_intrmtx, + cv_time_ms(20)); mutex_exit(&ha->ha_intrmtx); } } Index: dev/isa/fd.c =================================================================== RCS file: /cvsroot/src/sys/dev/isa/fd.c,v retrieving revision 1.87 diff -u -p -r1.87 fd.c --- dev/isa/fd.c 3 May 2008 08:23:41 -0000 1.87 +++ dev/isa/fd.c 7 May 2008 13:34:21 -0000 @@ -492,12 +492,13 @@ fdprobe(device_t parent, cfdata_t match, bus_space_write_1(iot, ioh, fdout, drive | FDO_FRST | FDO_MOEN(drive)); /* wait for motor to spin up */ /* XXX check sc_probe */ - (void) cv_timedwait(&fdc->sc_cv, &fdc->sc_mtx, hz / 4); + (void) cv_timedwait(&fdc->sc_cv, &fdc->sc_mtx, cv_time_tick(hz >> 2)); out_fdc(iot, ioh, NE7CMD_RECAL); out_fdc(iot, ioh, drive); /* wait for recalibrate, up to 2s */ /* XXX check sc_probe */ - if (cv_timedwait(&fdc->sc_cv, &fdc->sc_mtx, 2 * hz) != EWOULDBLOCK){ + if (cv_timedwait(&fdc->sc_cv, &fdc->sc_mtx, cv_time_sec(2)) != + EWOULDBLOCK) { #ifdef FD_DEBUG /* XXX */ printf("fdprobe: got intr\n"); Index: dev/pad/pad.c =================================================================== RCS file: /cvsroot/src/sys/dev/pad/pad.c,v retrieving revision 1.6 diff -u -p -r1.6 pad.c --- dev/pad/pad.c 4 Mar 2008 18:23:44 -0000 1.6 +++ dev/pad/pad.c 7 May 2008 13:34:21 -0000 @@ -376,7 +376,7 @@ pad_read(dev_t dev, struct uio *uio, int mutex_enter(&sc->sc_mutex); err = cv_timedwait_sig(&sc->sc_condvar, &sc->sc_mutex, - hz/100); + cv_time_tick(1)); if (err != 0 && err != EWOULDBLOCK) { mutex_exit(&sc->sc_mutex); aprint_error_dev(&sc->sc_dev, Index: dev/pci/arcmsr.c =================================================================== RCS file: /cvsroot/src/sys/dev/pci/arcmsr.c,v retrieving revision 1.20 diff -u -p -r1.20 arcmsr.c --- dev/pci/arcmsr.c 3 Apr 2008 13:59:00 -0000 1.20 +++ dev/pci/arcmsr.c 7 May 2008 13:34:22 -0000 @@ -1684,7 +1684,8 @@ arc_wait(struct arc_softc *sc) arc_write(sc, ARC_REG_INTRMASK, ~(ARC_REG_INTRMASK_POSTQUEUE|ARC_REG_INTRMASK_DOORBELL)); - if (cv_timedwait(&sc->sc_condvar, &sc->sc_mutex, hz) == EWOULDBLOCK) + if (cv_timedwait(&sc->sc_condvar, &sc->sc_mutex, cv_time_sec(1)) == + EWOULDBLOCK) arc_write(sc, ARC_REG_INTRMASK, ~ARC_REG_INTRMASK_POSTQUEUE); } Index: kern/kern_condvar.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_condvar.c,v retrieving revision 1.17 diff -u -p -r1.17 kern_condvar.c --- kern/kern_condvar.c 28 Apr 2008 20:24:02 -0000 1.17 +++ kern/kern_condvar.c 7 May 2008 13:34:23 -0000 @@ -44,6 +44,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_condvar #include #include #include +#include #include #include @@ -218,7 +219,7 @@ cv_wait_sig(kcondvar_t *cv, kmutex_t *mt * timeout expired. */ int -cv_timedwait(kcondvar_t *cv, kmutex_t *mtx, int timo) +cv_timedwait(kcondvar_t *cv, kmutex_t *mtx, clock_t when) { lwp_t *l = curlwp; sleepq_t *sq; @@ -226,11 +227,17 @@ cv_timedwait(kcondvar_t *cv, kmutex_t *m KASSERT(mutex_owned(mtx)); - if (sleepq_dontsleep(l)) + if (sleepq_dontsleep(l)) { return sleepq_abort(mtx, 0); - + } + if ((int)when < 0) { + return -(int)when; + } + if (when != 0 && (int)(when -= hardclock_ticks) <= 0) { + return EWOULDBLOCK; + } sq = cv_enter(cv, mtx, l); - error = sleepq_block(timo, false); + error = sleepq_block((int)when, false); return cv_exit(cv, mtx, l, error); } @@ -244,7 +251,7 @@ cv_timedwait(kcondvar_t *cv, kmutex_t *m * call is restartable, or EINTR otherwise. */ int -cv_timedwait_sig(kcondvar_t *cv, kmutex_t *mtx, int timo) +cv_timedwait_sig(kcondvar_t *cv, kmutex_t *mtx, clock_t when) { lwp_t *l = curlwp; sleepq_t *sq; @@ -252,11 +259,17 @@ cv_timedwait_sig(kcondvar_t *cv, kmutex_ KASSERT(mutex_owned(mtx)); - if (sleepq_dontsleep(l)) + if (sleepq_dontsleep(l)) { return sleepq_abort(mtx, 0); - + } + if ((int)when < 0) { + return -(int)when; + } + if (when != 0 && (int)(when -= hardclock_ticks) <= 0) { + return EWOULDBLOCK; + } sq = cv_enter(cv, mtx, l); - error = sleepq_block(timo, true); + error = sleepq_block((int)when, true); return cv_exit(cv, mtx, l, error); } @@ -374,3 +387,103 @@ cv_is_valid(kcondvar_t *cv) } return cv->cv_waiters >= 0; } + +/* + * cv_time_sec: + * + * Given number of seconds into the future, return suitable + * parameter for cv_timedwait_*(). + */ +clock_t +cv_time_sec(int sec) +{ + + if (sec <= 0) { + return (clock_t)-EWOULDBLOCK; + } + return hardclock_ticks + hz * sec; +} + +/* + * cv_time_tick: + * + * Given number of clock ticks into the future, return suitable + * parameter for cv_timedwait_*(). + */ +clock_t +cv_time_tick(int ticks) +{ + + if (ticks <= 0) { + return (clock_t)-EWOULDBLOCK; + } + return hardclock_ticks + ticks; +} + +/* + * cv_time_ms: + * + * Given number of miliseconds into the future, return suitable + * parameter for cv_timedwait_*(). + */ +clock_t +cv_time_ms(int ms) +{ + + if (ms <= 0) { + return (clock_t)-EWOULDBLOCK; + } + return hardclock_ticks + mstohz(ms); +} + +/* + * cv_time_val: + * + * Given an absolute time or interval coded as a timeval, + * return suitable parameter for cv_timedwait_*(). + */ +clock_t +cv_time_val(struct timeval *tv, bool absolute) +{ + struct timeval tvx; + + if (absolute) { + getmicrotime(&tvx); + timersub(tv, &tvx, &tvx); + } else { + tvx = *tv; + } + if (tvx.tv_sec < 0 || (tvx.tv_sec == 0 && tvx.tv_usec <= 0)) { + return (clock_t)-EWOULDBLOCK; + } + if (itimerfix(&tvx) != 0) { + return (clock_t)-EINVAL; + } + return hardclock_ticks + tvtohz(&tvx); +} + +/* + * cv_time_spec: + * + * Given absolute time or interval coded as a timespec, + * return suitable parameter for cv_timedwait_*(). + */ +clock_t +cv_time_spec(struct timespec *tv, bool absolute) +{ + struct timespec tvx; + + if (absolute) { + getnanotime(&tvx); + timespecsub(tv, &tvx, &tvx); + } else { + tvx = *tv; + } + if (tvx.tv_sec < 0 || (tvx.tv_sec == 0 && tvx.tv_nsec <= 0)) { + return (clock_t)-EWOULDBLOCK; + } + if (itimespecfix(&tvx) != 0) { + return (clock_t)-EINVAL; + } + return hardclock_ticks + tstohz(&tvx); +} Index: kern/kern_ktrace.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_ktrace.c,v retrieving revision 1.144 diff -u -p -r1.144 kern_ktrace.c --- kern/kern_ktrace.c 29 Apr 2008 15:55:24 -0000 1.144 +++ kern/kern_ktrace.c 7 May 2008 13:34:23 -0000 @@ -355,7 +355,7 @@ ktraddentry(lwp_t *l, struct ktrace_entr getmicrouptime(&t1); #endif if (cv_timedwait(&ktd->ktd_sync_cv, &ktrace_lock, - ktd_timeout * hz) != 0) { + cv_time_sec(ktd_timeout)) != 0) { ktd->ktd_flags |= KTDF_BLOCKING; /* * Maybe the writer thread is blocking Index: kern/sys_aio.c =================================================================== RCS file: /cvsroot/src/sys/kern/sys_aio.c,v retrieving revision 1.18 diff -u -p -r1.18 sys_aio.c --- kern/sys_aio.c 24 Apr 2008 18:39:24 -0000 1.18 +++ kern/sys_aio.c 7 May 2008 13:34:24 -0000 @@ -737,7 +737,8 @@ sys_aio_suspend(struct lwp *l, const str struct aio_job *a_job; struct aiocb **aiocbp_list; struct timespec ts; - int i, error, nent, timo; + int i, error, nent; + clock_t timo; if (p->p_aio == NULL) return EAGAIN; @@ -753,11 +754,7 @@ sys_aio_suspend(struct lwp *l, const str sizeof(struct timespec)); if (error) return error; - timo = mstohz((ts.tv_sec * 1000) + (ts.tv_nsec / 1000000)); - if (timo == 0 && ts.tv_sec == 0 && ts.tv_nsec > 0) - timo = 1; - if (timo <= 0) - return EAGAIN; + timo = cv_time_spec(&ts, false); } else timo = 0; Index: kern/sys_mqueue.c =================================================================== RCS file: /cvsroot/src/sys/kern/sys_mqueue.c,v retrieving revision 1.10 diff -u -p -r1.10 sys_mqueue.c --- kern/sys_mqueue.c 24 Apr 2008 15:35:30 -0000 1.10 +++ kern/sys_mqueue.c 7 May 2008 13:34:25 -0000 @@ -199,30 +199,6 @@ mqueue_get(struct lwp *l, mqd_t mqd, mod return 0; } -/* - * Converter from struct timespec to the ticks. - * Used by mq_timedreceive(), mq_timedsend(). - */ -static int -abstimeout2timo(const void *uaddr, int *timo) -{ - struct timespec ts; - int error; - - error = copyin(uaddr, &ts, sizeof(struct timespec)); - if (error) - return error; - - /* - * According to POSIX, validation check is needed only in case of - * blocking. Thus, set the invalid value right now, and fail latter. - */ - error = itimespecfix(&ts); - *timo = (error == 0) ? tstohz(&ts) : -1; - - return 0; -} - static int mq_poll_fop(file_t *fp, int events) { @@ -462,7 +438,7 @@ sys_mq_close(struct lwp *l, const struct */ static int mq_receive1(struct lwp *l, mqd_t mqdes, void *msg_ptr, size_t msg_len, - unsigned *msg_prio, int t, ssize_t *mlen) + unsigned *msg_prio, clock_t t, ssize_t *mlen) { file_t *fp = NULL; struct mqueue *mq; @@ -487,10 +463,6 @@ mq_receive1(struct lwp *l, mqd_t mqdes, error = EAGAIN; goto error; } - if (t < 0) { - error = EINVAL; - goto error; - } /* * Block until someone sends the message. * While doing this, notification should not be sent. @@ -567,14 +539,17 @@ sys_mq_timedreceive(struct lwp *l, const syscallarg(unsigned *) msg_prio; syscallarg(const struct timespec *) abs_timeout; } */ - int error, t; + struct timespec ts; + int error; ssize_t mlen; + clock_t t; /* Get and convert time value */ if (SCARG(uap, abs_timeout)) { - error = abstimeout2timo(SCARG(uap, abs_timeout), &t); + error = copyin(SCARG(uap, abs_timeout), &ts, sizeof(ts)); if (error) return error; + t = cv_time_spec(&ts, true); } else t = 0; @@ -591,7 +566,7 @@ sys_mq_timedreceive(struct lwp *l, const */ static int mq_send1(struct lwp *l, mqd_t mqdes, const char *msg_ptr, size_t msg_len, - unsigned msg_prio, int t) + unsigned msg_prio, clock_t t) { file_t *fp = NULL; struct mqueue *mq; @@ -644,10 +619,6 @@ mq_send1(struct lwp *l, mqd_t mqdes, con error = EAGAIN; goto error; } - if (t < 0) { - error = EINVAL; - goto error; - } /* Block until queue becomes available */ error = cv_timedwait_sig(&mq->mq_recv_cv, &mq->mq_mtx, t); if (error || (mq->mq_attrib.mq_flags & MQ_UNLINK)) { @@ -727,13 +698,16 @@ sys_mq_timedsend(struct lwp *l, const st syscallarg(unsigned) msg_prio; syscallarg(const struct timespec *) abs_timeout; } */ - int t; + struct timespec ts; + int error; + clock_t t; /* Get and convert time value */ if (SCARG(uap, abs_timeout)) { - int error = abstimeout2timo(SCARG(uap, abs_timeout), &t); + error = copyin(SCARG(uap, abs_timeout), &ts, sizeof(ts)); if (error) return error; + t = cv_time_spec(&ts, true); } else t = 0; Index: kern/sys_sig.c =================================================================== RCS file: /cvsroot/src/sys/kern/sys_sig.c,v retrieving revision 1.15 diff -u -p -r1.15 sys_sig.c --- kern/sys_sig.c 28 Apr 2008 20:24:05 -0000 1.15 +++ kern/sys_sig.c 7 May 2008 13:34:25 -0000 @@ -616,33 +616,27 @@ __sigtimedwait1(struct lwp *l, const str } */ struct proc *p = l->l_proc; int error, signum; - int timo = 0; struct timespec ts, tsstart, tsnow; ksiginfo_t *ksi; + clock_t timo; memset(&tsstart, 0, sizeof tsstart); /* XXX gcc */ /* * Calculate timeout, if it was specified. */ + timo = 0; if (SCARG(uap, timeout)) { - uint64_t ms; - if ((error = (*fetch_timeout)(SCARG(uap, timeout), &ts, sizeof(ts)))) return (error); - ms = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000); - timo = mstohz(ms); - if (timo == 0 && ts.tv_sec == 0 && ts.tv_nsec > 0) - timo = 1; - if (timo <= 0) - return (EAGAIN); - /* * Remember current uptime, it would be used in * ECANCELED/ERESTART case. */ + timo = cv_time_spec(&ts, false); getnanouptime(&tsstart); + timespecadd(&ts, &ts, &tsstart); } error = copyin(SCARG(uap, set), &l->l_sigwaitset, Index: kern/tty.c =================================================================== RCS file: /cvsroot/src/sys/kern/tty.c,v retrieving revision 1.223 diff -u -p -r1.223 tty.c --- kern/tty.c 3 May 2008 05:34:23 -0000 1.223 +++ kern/tty.c 7 May 2008 13:34:28 -0000 @@ -2571,14 +2571,17 @@ ttysleep(struct tty *tp, kcondvar_t *cv, { int error; short gen; + clock_t t; KASSERT(mutex_owned(&tty_lock)); gen = tp->t_gen; + if ((t = (clock_t)timo) != 0) + t = cv_time_tick(timo); if (catch) - error = cv_timedwait_sig(cv, &tty_lock, timo); + error = cv_timedwait_sig(cv, &tty_lock, t); else - error = cv_timedwait(cv, &tty_lock, timo); + error = cv_timedwait(cv, &tty_lock, t); if (error != 0) return (error); return (tp->t_gen == gen ? 0 : ERESTART); Index: kern/uipc_socket2.c =================================================================== RCS file: /cvsroot/src/sys/kern/uipc_socket2.c,v retrieving revision 1.92 diff -u -p -r1.92 uipc_socket2.c --- kern/uipc_socket2.c 28 Apr 2008 20:24:05 -0000 1.92 +++ kern/uipc_socket2.c 7 May 2008 13:34:29 -0000 @@ -400,6 +400,7 @@ sbwait(struct sockbuf *sb) { struct socket *so; kmutex_t *lock; + clock_t when; int error; so = sb->sb_so; @@ -408,10 +409,12 @@ sbwait(struct sockbuf *sb) sb->sb_flags |= SB_NOTIFY; lock = so->so_lock; + if ((when = (clock_t)sb->sb_timeo) != 0) + when = cv_time_tick(sb->sb_timeo); if ((sb->sb_flags & SB_NOINTR) != 0) - error = cv_timedwait(&sb->sb_cv, lock, sb->sb_timeo); + error = cv_timedwait(&sb->sb_cv, lock, when); else - error = cv_timedwait_sig(&sb->sb_cv, lock, sb->sb_timeo); + error = cv_timedwait_sig(&sb->sb_cv, lock, when); if (__predict_false(lock != so->so_lock)) solockretry(so, lock); return error; @@ -1391,11 +1394,14 @@ sowait(struct socket *so, int timo) { kmutex_t *lock; int error; + clock_t when; KASSERT(solocked(so)); lock = so->so_lock; - error = cv_timedwait_sig(&so->so_cv, lock, timo); + if ((when = (clock_t)timo) != 0) + when = cv_time_tick(timo); + error = cv_timedwait_sig(&so->so_cv, lock, when); if (__predict_false(lock != so->so_lock)) solockretry(so, lock); return error; Index: kern/vfs_bio.c =================================================================== RCS file: /cvsroot/src/sys/kern/vfs_bio.c,v retrieving revision 1.197 diff -u -p -r1.197 vfs_bio.c --- kern/vfs_bio.c 5 May 2008 17:11:17 -0000 1.197 +++ kern/vfs_bio.c 7 May 2008 13:34:30 -0000 @@ -628,7 +628,8 @@ buf_malloc(size_t size) } /* Wait for buffers to arrive on the LRU queue */ - cv_timedwait(&needbuffer_cv, &bufcache_lock, hz / 4); + cv_timedwait(&needbuffer_cv, &bufcache_lock, + cv_time_tick(hz >> 2)); mutex_exit(&bufcache_lock); } @@ -1276,6 +1277,7 @@ getnewbuf(int slpflag, int slptimeo, int { buf_t *bp; struct vnode *vp; + clock_t when; start: KASSERT(mutex_owned(&bufcache_lock)); @@ -1311,12 +1313,14 @@ getnewbuf(int slpflag, int slptimeo, int */ if (!from_bufq || curlwp != uvm.pagedaemon_lwp) { /* wait for a free buffer of any kind */ + if ((when = (clock_t)slptimeo) != 0) + when = cv_time_tick(slptimeo); if ((slpflag & PCATCH) != 0) (void)cv_timedwait_sig(&needbuffer_cv, - &bufcache_lock, slptimeo); + &bufcache_lock, when); else (void)cv_timedwait(&needbuffer_cv, - &bufcache_lock, slptimeo); + &bufcache_lock, when); } return (NULL); } @@ -2019,6 +2023,7 @@ int bbusy(buf_t *bp, bool intr, int timo, kmutex_t *interlock) { int error; + clock_t when; KASSERT(mutex_owned(&bufcache_lock)); @@ -2029,12 +2034,14 @@ bbusy(buf_t *bp, bool intr, int timo, km bref(bp); if (interlock != NULL) mutex_exit(interlock); + if ((when = (clock_t)timo) != 0) + when = cv_time_tick(timo); if (intr) { error = cv_timedwait_sig(&bp->b_busy, &bufcache_lock, - timo); + when); } else { error = cv_timedwait(&bp->b_busy, &bufcache_lock, - timo); + when); } brele(bp); if (interlock != NULL) Index: kern/vfs_subr.c =================================================================== RCS file: /cvsroot/src/sys/kern/vfs_subr.c,v retrieving revision 1.344 diff -u -p -r1.344 vfs_subr.c --- kern/vfs_subr.c 6 May 2008 18:43:44 -0000 1.344 +++ kern/vfs_subr.c 7 May 2008 13:34:32 -0000 @@ -973,7 +973,8 @@ vrele_thread(void *cookie) for (;;) { mutex_enter(&vrele_lock); while (TAILQ_EMPTY(&vrele_list)) { - cv_timedwait(&vrele_cv, &vrele_lock, hz); + (void)cv_timedwait(&vrele_cv, &vrele_lock, + cv_time_sec(1)); } vp = TAILQ_FIRST(&vrele_list); TAILQ_REMOVE(&vrele_list, vp, v_freelist); Index: miscfs/syncfs/sync_subr.c =================================================================== RCS file: /cvsroot/src/sys/miscfs/syncfs/sync_subr.c,v retrieving revision 1.34 diff -u -p -r1.34 sync_subr.c --- miscfs/syncfs/sync_subr.c 2 Jan 2008 11:49:02 -0000 1.34 +++ miscfs/syncfs/sync_subr.c 7 May 2008 13:34:33 -0000 @@ -274,8 +274,10 @@ sched_sync(void *v) * are just trying to generally pace the * filesystem activity. */ - if (time_second == starttime) - cv_timedwait(&syncer_cv, &syncer_data_lock, hz); + if (time_second == starttime) { + (void)cv_timedwait(&syncer_cv, + &syncer_data_lock, cv_time_sec(1)); + } } mutex_exit(&syncer_data_lock); } Index: netbt/hci_unit.c =================================================================== RCS file: /cvsroot/src/sys/netbt/hci_unit.c,v retrieving revision 1.11 diff -u -p -r1.11 hci_unit.c --- netbt/hci_unit.c 24 Apr 2008 11:38:37 -0000 1.11 +++ netbt/hci_unit.c 7 May 2008 13:34:33 -0000 @@ -180,7 +180,8 @@ hci_enable(struct hci_unit *unit) goto bad2; while (unit->hci_flags & BTF_INIT) { - err = cv_timedwait_sig(&unit->hci_init, bt_lock, 5 * hz); + err = cv_timedwait_sig(&unit->hci_init, bt_lock, + cv_time_sec(5)); if (err) goto bad2; Index: nfs/nfs_bio.c =================================================================== RCS file: /cvsroot/src/sys/nfs/nfs_bio.c,v retrieving revision 1.175 diff -u -p -r1.175 nfs_bio.c --- nfs/nfs_bio.c 24 Apr 2008 15:35:31 -0000 1.175 +++ nfs/nfs_bio.c 7 May 2008 13:34:33 -0000 @@ -724,7 +724,8 @@ nfs_asyncio(struct buf *bp) { struct nfs_iod *iod; struct nfsmount *nmp; - int slptimeo = 0, error; + clock_t slptimeo = 0; + int error; bool catch = false; if (nfs_numasync == 0) @@ -796,10 +797,10 @@ again: mutex_exit(&nmp->nm_lock); return (EINTR); } - if (catch) { - catch = false; - slptimeo = 2 * hz; + if (slptimeo || catch) { + slptimeo = cv_time_sec(2); } + catch = false; } /* Index: nfs/nfs_kq.c =================================================================== RCS file: /cvsroot/src/sys/nfs/nfs_kq.c,v retrieving revision 1.22 diff -u -p -r1.22 nfs_kq.c --- nfs/nfs_kq.c 28 Apr 2008 20:24:10 -0000 1.22 +++ nfs/nfs_kq.c 7 May 2008 13:34:33 -0000 @@ -159,8 +159,8 @@ nfs_kqpoll(void *arg) } /* wait a while before checking for changes again */ - cv_timedwait(&nfskq_cv, &nfskevq_lock, - NFS_MINATTRTIMO * hz / 2); + (void)cv_timedwait(&nfskq_cv, &nfskevq_lock, + cv_time_tick(NFS_MINATTRTIMO * hz >> 1)); } } Index: nfs/nfs_socket.c =================================================================== RCS file: /cvsroot/src/sys/nfs/nfs_socket.c,v retrieving revision 1.170 diff -u -p -r1.170 nfs_socket.c --- nfs/nfs_socket.c 24 Apr 2008 11:38:39 -0000 1.170 +++ nfs/nfs_socket.c 7 May 2008 13:34:34 -0000 @@ -1793,7 +1793,7 @@ static int nfs_sndlock(struct nfsmount *nmp, struct nfsreq *rep) { struct lwp *l; - int timeo = 0; + clock_t timeo = 0; bool catch = false; int error = 0; @@ -1814,10 +1814,10 @@ nfs_sndlock(struct nfsmount *nmp, struct } else { cv_timedwait(&nmp->nm_sndcv, &nmp->nm_lock, timeo); } - if (catch) { - catch = false; - timeo = 2 * hz; + if (catch || timeo) { + timeo = cv_time_sec(2); } + catch = false; } nmp->nm_iflag |= NFSMNT_SNDLOCK; quit: @@ -1844,7 +1844,7 @@ static int nfs_rcvlock(struct nfsmount *nmp, struct nfsreq *rep) { int *flagp = &nmp->nm_iflag; - int slptimeo = 0; + clock_t slptimeo = 0; bool catch; int error = 0; @@ -1882,10 +1882,10 @@ nfs_rcvlock(struct nfsmount *nmp, struct cv_timedwait(&nmp->nm_rcvcv, &nmp->nm_lock, slptimeo); } - if (catch) { - catch = false; - slptimeo = 2 * hz; + if (catch || slptimeo) { + slptimeo = cv_time_sec(2); } + catch = false; } mutex_exit(&nmp->nm_lock); return error; Index: sys/condvar.h =================================================================== RCS file: /cvsroot/src/sys/sys/condvar.h,v retrieving revision 1.9 diff -u -p -r1.9 condvar.h --- sys/condvar.h 28 Apr 2008 20:24:10 -0000 1.9 +++ sys/condvar.h 7 May 2008 13:34:35 -0000 @@ -48,13 +48,24 @@ typedef struct kcondvar { #ifdef _KERNEL +#include /* XXX clock_t */ + +struct timeval; +struct timespec; + void cv_init(kcondvar_t *, const char *); void cv_destroy(kcondvar_t *); void cv_wait(kcondvar_t *, kmutex_t *); int cv_wait_sig(kcondvar_t *, kmutex_t *); -int cv_timedwait(kcondvar_t *, kmutex_t *, int); -int cv_timedwait_sig(kcondvar_t *, kmutex_t *, int); +int cv_timedwait(kcondvar_t *, kmutex_t *, clock_t); +int cv_timedwait_sig(kcondvar_t *, kmutex_t *, clock_t); + +clock_t cv_time_sec(int); +clock_t cv_time_tick(int); +clock_t cv_time_ms(int); +clock_t cv_time_val(struct timeval *, bool); +clock_t cv_time_spec(struct timespec *, bool); void cv_signal(kcondvar_t *); void cv_broadcast(kcondvar_t *); Index: ufs/lfs/lfs_bio.c =================================================================== RCS file: /cvsroot/src/sys/ufs/lfs/lfs_bio.c,v retrieving revision 1.114 diff -u -p -r1.114 lfs_bio.c --- ufs/lfs/lfs_bio.c 6 May 2008 18:43:45 -0000 1.114 +++ ufs/lfs/lfs_bio.c 7 May 2008 13:34:35 -0000 @@ -160,7 +160,7 @@ lfs_reservebuf(struct lfs *fs, struct vn lfs_flush(fs, 0, 0); error = cv_timedwait_sig(&locked_queue_cv, &lfs_lock, - hz * LFS_BUFWAIT); + cv_time_sec(LFS_BUFWAIT)); if (error && error != EWOULDBLOCK) { mutex_exit(&lfs_lock); return error; @@ -716,7 +716,7 @@ lfs_check(struct vnode *vp, daddr_t blkn DLOG((DLOG_AVAIL, "lfs_check: waiting: count=%d, bytes=%ld\n", locked_queue_count, locked_queue_bytes)); error = cv_timedwait_sig(&locked_queue_cv, &lfs_lock, - hz * LFS_BUFWAIT); + cv_time_sec(LFS_BUFWAIT)); if (error != EWOULDBLOCK) break; Index: uvm/uvm_map.c =================================================================== RCS file: /cvsroot/src/sys/uvm/uvm_map.c,v retrieving revision 1.254 diff -u -p -r1.254 uvm_map.c --- uvm/uvm_map.c 27 Apr 2008 11:39:47 -0000 1.254 +++ uvm/uvm_map.c 7 May 2008 13:34:38 -0000 @@ -1181,7 +1181,8 @@ retry: "<- uvm_map_findspace failed!", 0,0,0,0); return ENOMEM; } else { - cv_timedwait(&map->cv, &map->misc_lock, hz); + (void)cv_timedwait(&map->cv, &map->misc_lock, + cv_time_sec(1)); } } mutex_exit(&map->misc_lock);