From owner-svn-src-head@FreeBSD.ORG Mon Mar 4 16:41:28 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 8DFFBF99; Mon, 4 Mar 2013 16:41:28 +0000 (UTC) (envelope-from davide@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 808EB764; Mon, 4 Mar 2013 16:41:28 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id r24GfSS6025065; Mon, 4 Mar 2013 16:41:28 GMT (envelope-from davide@svn.freebsd.org) Received: (from davide@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r24GfSUD025064; Mon, 4 Mar 2013 16:41:28 GMT (envelope-from davide@svn.freebsd.org) Message-Id: <201303041641.r24GfSUD025064@svn.freebsd.org> From: Davide Italiano Date: Mon, 4 Mar 2013 16:41:28 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r247801 - head/sys/kern X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 04 Mar 2013 16:41:28 -0000 Author: davide Date: Mon Mar 4 16:41:27 2013 New Revision: 247801 URL: http://svnweb.freebsd.org/changeset/base/247801 Log: MFcalloutng: Fix kern_select() and sys_poll() so that they can handle sub-tick precision for timeouts (in the same fashion it was done for nanosleep() in r247797). Sponsored by: Google Summer of Code 2012, iXsystems inc. Tested by: flo, marius, ian, markj, Fabian Keil Modified: head/sys/kern/sys_generic.c Modified: head/sys/kern/sys_generic.c ============================================================================== --- head/sys/kern/sys_generic.c Mon Mar 4 16:25:12 2013 (r247800) +++ head/sys/kern/sys_generic.c Mon Mar 4 16:41:27 2013 (r247801) @@ -103,7 +103,7 @@ static int dofilewrite(struct thread *, off_t, int); static void doselwakeup(struct selinfo *, int); static void seltdinit(struct thread *); -static int seltdwait(struct thread *, int); +static int seltdwait(struct thread *, sbintime_t, sbintime_t); static void seltdclear(struct thread *); /* @@ -950,9 +950,10 @@ kern_select(struct thread *td, int nd, f */ fd_mask s_selbits[howmany(2048, NFDBITS)]; fd_mask *ibits[3], *obits[3], *selbits, *sbp; - struct timeval atv, rtv, ttv; - int error, lf, ndu, timo; + struct timeval rtv; + sbintime_t asbt, precision, rsbt; u_int nbufbytes, ncpbytes, ncpubytes, nfdbits; + int error, lf, ndu; if (nd < 0) return (EINVAL); @@ -1042,35 +1043,29 @@ kern_select(struct thread *td, int nd, f if (nbufbytes != 0) bzero(selbits, nbufbytes / 2); + precision = 0; if (tvp != NULL) { - atv = *tvp; - if (itimerfix(&atv)) { + rtv = *tvp; + if (rtv.tv_sec < 0 || rtv.tv_usec < 0 || + rtv.tv_usec >= 1000000) { error = EINVAL; goto done; } - getmicrouptime(&rtv); - timevaladd(&atv, &rtv); - } else { - atv.tv_sec = 0; - atv.tv_usec = 0; - } - timo = 0; + rsbt = tvtosbt(rtv); + precision = rsbt; + precision >>= tc_precexp; + if (TIMESEL(&asbt, rsbt)) + asbt += tc_tick_sbt; + asbt += rsbt; + } else + asbt = -1; seltdinit(td); /* Iterate until the timeout expires or descriptors become ready. */ for (;;) { error = selscan(td, ibits, obits, nd); if (error || td->td_retval[0] != 0) break; - if (atv.tv_sec || atv.tv_usec) { - getmicrouptime(&rtv); - if (timevalcmp(&rtv, &atv, >=)) - break; - ttv = atv; - timevalsub(&ttv, &rtv); - timo = ttv.tv_sec > 24 * 60 * 60 ? - 24 * 60 * 60 * hz : tvtohz(&ttv); - } - error = seltdwait(td, timo); + error = seltdwait(td, asbt, precision); if (error) break; error = selrescan(td, ibits, obits); @@ -1278,9 +1273,9 @@ sys_poll(td, uap) { struct pollfd *bits; struct pollfd smallbits[32]; - struct timeval atv, rtv, ttv; - int error, timo; + sbintime_t asbt, precision, rsbt; u_int nfds; + int error; size_t ni; nfds = uap->nfds; @@ -1294,36 +1289,27 @@ sys_poll(td, uap) error = copyin(uap->fds, bits, ni); if (error) goto done; + precision = 0; if (uap->timeout != INFTIM) { - atv.tv_sec = uap->timeout / 1000; - atv.tv_usec = (uap->timeout % 1000) * 1000; - if (itimerfix(&atv)) { + if (uap->timeout < 0) { error = EINVAL; goto done; } - getmicrouptime(&rtv); - timevaladd(&atv, &rtv); - } else { - atv.tv_sec = 0; - atv.tv_usec = 0; - } - timo = 0; + rsbt = SBT_1MS * uap->timeout; + precision = rsbt; + precision >>= tc_precexp; + if (TIMESEL(&asbt, rsbt)) + asbt += tc_tick_sbt; + asbt += rsbt; + } else + asbt = -1; seltdinit(td); /* Iterate until the timeout expires or descriptors become ready. */ for (;;) { error = pollscan(td, bits, nfds); if (error || td->td_retval[0] != 0) break; - if (atv.tv_sec || atv.tv_usec) { - getmicrouptime(&rtv); - if (timevalcmp(&rtv, &atv, >=)) - break; - ttv = atv; - timevalsub(&ttv, &rtv); - timo = ttv.tv_sec > 24 * 60 * 60 ? - 24 * 60 * 60 * hz : tvtohz(&ttv); - } - error = seltdwait(td, timo); + error = seltdwait(td, asbt, precision); if (error) break; error = pollrescan(td); @@ -1667,7 +1653,7 @@ out: } static int -seltdwait(struct thread *td, int timo) +seltdwait(struct thread *td, sbintime_t sbt, sbintime_t precision) { struct seltd *stp; int error; @@ -1686,8 +1672,11 @@ seltdwait(struct thread *td, int timo) mtx_unlock(&stp->st_mtx); return (0); } - if (timo > 0) - error = cv_timedwait_sig(&stp->st_wait, &stp->st_mtx, timo); + if (sbt == 0) + error = EWOULDBLOCK; + else if (sbt != -1) + error = cv_timedwait_sig_sbt(&stp->st_wait, &stp->st_mtx, + sbt, precision, C_ABSOLUTE); else error = cv_wait_sig(&stp->st_wait, &stp->st_mtx); mtx_unlock(&stp->st_mtx);