From a36f8271cbe1fe2c9def06c66e3a077f13a6f19c Mon Sep 17 00:00:00 2001 From: cheloha Date: Tue, 4 Sep 2018 02:38:25 +0000 Subject: [PATCH] kevent: Don't poll for nonzero timeouts < 1us. Instead of truncating nanosecond timeouts to zero here and polling, we should round up to a delay of at least a tick, just like all the other timespec syscalls. Fixed in NetBSD kern_event.c v1.62 and FreeBSD r247804. ok millert@ visa@ --- sys/kern/kern_event.c | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index 81b591837c7..1af10f0b1b9 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_event.c,v 1.98 2018/08/20 16:00:22 mpi Exp $ */ +/* $OpenBSD: kern_event.c,v 1.99 2018/09/04 02:38:25 cheloha Exp $ */ /*- * Copyright (c) 1999,2000,2001 Jonathan Lemon @@ -694,8 +694,7 @@ kqueue_scan(struct kqueue *kq, int maxevents, struct kevent *ulistp, const struct timespec *tsp, struct proc *p, int *retval) { struct kevent *kevp; - struct timespec ats; - struct timeval atv, rtv, ttv; + struct timespec ats, rts, tts; struct knote *kn, marker; int s, count, timeout, nkev = 0, error = 0; struct kevent kev[KQ_NEVENTS]; @@ -706,39 +705,36 @@ kqueue_scan(struct kqueue *kq, int maxevents, struct kevent *ulistp, if (tsp != NULL) { ats = *tsp; - if (timespecfix(&ats)) { - error = EINVAL; - goto done; - } - TIMESPEC_TO_TIMEVAL(&atv, &ats); - if (atv.tv_sec == 0 && atv.tv_usec == 0) { + if (!timespecisset(&ats)) { /* No timeout, just poll */ timeout = -1; goto start; } - itimerround(&atv); + if (timespecfix(&ats)) { + error = EINVAL; + goto done; + } - timeout = atv.tv_sec > 24 * 60 * 60 ? - 24 * 60 * 60 * hz : tvtohz(&atv); + timeout = ats.tv_sec > 24 * 60 * 60 ? + 24 * 60 * 60 * hz : tstohz(&ats); - getmicrouptime(&rtv); - timeradd(&atv, &rtv, &atv); + getnanouptime(&rts); + timespecadd(&ats, &rts, &ats); } else { - atv.tv_sec = 0; - atv.tv_usec = 0; + timespecclear(&ats); timeout = 0; } goto start; retry: - if (atv.tv_sec || atv.tv_usec) { - getmicrouptime(&rtv); - if (timercmp(&rtv, &atv, >=)) + if (timespecisset(&ats)) { + getnanouptime(&rts); + if (timespeccmp(&rts, &ats, >=)) goto done; - ttv = atv; - timersub(&ttv, &rtv, &ttv); - timeout = ttv.tv_sec > 24 * 60 * 60 ? - 24 * 60 * 60 * hz : tvtohz(&ttv); + tts = ats; + timespecsub(&tts, &rts, &tts); + timeout = tts.tv_sec > 24 * 60 * 60 ? + 24 * 60 * 60 * hz : tstohz(&tts); } start: -- 2.20.1