Date: Sun, 17 Jun 2012 20:45:45 +0000 (UTC) From: Davide Italiano <davide@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r237202 - in projects/calloutng/sys: kern sys Message-ID: <201206172045.q5HKjj92031635@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: davide Date: Sun Jun 17 20:45:45 2012 New Revision: 237202 URL: http://svn.freebsd.org/changeset/base/237202 Log: - Extend the condvar(9) KPI introducing a new cv_timedwait_bt_sig() function so that we can specify timeout precision in terms of struct bintime. - Now seltdwait() takes three argument rather than two so that their consumers can specify if the timeout should be passed as ticks or bintime. - Refactor the kern_select() and the sys_poll() code so that these two services may rely on cv_timedwait_bt_sig() rather than on the previous less precise cv_timedwait_sig(). - Rethink the sleepqueue(9) KPI in order to make an attempt of avoiding both code duplication and breakages. Your mileage WILL vary, feel free to comment. Reviewed by: mav Modified: projects/calloutng/sys/kern/kern_condvar.c projects/calloutng/sys/kern/subr_sleepqueue.c projects/calloutng/sys/kern/sys_generic.c projects/calloutng/sys/sys/condvar.h projects/calloutng/sys/sys/sleepqueue.h Modified: projects/calloutng/sys/kern/kern_condvar.c ============================================================================== --- projects/calloutng/sys/kern/kern_condvar.c Sun Jun 17 19:16:31 2012 (r237201) +++ projects/calloutng/sys/kern/kern_condvar.c Sun Jun 17 20:45:45 2012 (r237202) @@ -342,7 +342,8 @@ _cv_timedwait(struct cv *cvp, struct loc * a signal was caught. */ int -_cv_timedwait_sig(struct cv *cvp, struct lock_object *lock, int timo) +_cv_timedwait_sig(struct cv *cvp, struct lock_object *lock, + struct bintime *bt, int timo) { WITNESS_SAVE_DECL(lock_witness); struct lock_class *class; @@ -379,7 +380,10 @@ _cv_timedwait_sig(struct cv *cvp, struct sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR | SLEEPQ_INTERRUPTIBLE, 0); - sleepq_set_timeout(cvp, timo); + if (bt == NULL) + sleepq_set_timeout(cvp, timo); + else + sleepq_set_timeout_bt(cvp, *bt); if (lock != &Giant.lock_object) { if (class->lc_flags & LC_SLEEPABLE) sleepq_release(cvp); Modified: projects/calloutng/sys/kern/subr_sleepqueue.c ============================================================================== --- projects/calloutng/sys/kern/subr_sleepqueue.c Sun Jun 17 19:16:31 2012 (r237201) +++ projects/calloutng/sys/kern/subr_sleepqueue.c Sun Jun 17 20:45:45 2012 (r237202) @@ -362,7 +362,7 @@ sleepq_add(void *wchan, struct lock_obje * sleep queue after timo ticks if the thread has not already been awakened. */ void -sleepq_set_timeout_bt(void *wchan, struct bintime bt) +_sleepq_set_timeout(void *wchan, struct bintime *bt, int timo) { struct sleepqueue_chain *sc; @@ -374,22 +374,12 @@ sleepq_set_timeout_bt(void *wchan, struc MPASS(TD_ON_SLEEPQ(td)); MPASS(td->td_sleepqueue == NULL); MPASS(wchan != NULL); - callout_reset_bt_on(&td->td_slpcallout, bt, sleepq_timeout, td, PCPU_GET(cpuid), 0); -} - -void -sleepq_set_timeout(void *wchan, int timo) -{ - struct sleepqueue_chain *sc; - struct thread *td; - - td = curthread; - sc = SC_LOOKUP(wchan); - mtx_assert(&sc->sc_lock, MA_OWNED); - MPASS(TD_ON_SLEEPQ(td)); - MPASS(td->td_sleepqueue == NULL); - MPASS(wchan != NULL); - callout_reset_curcpu(&td->td_slpcallout, timo, sleepq_timeout, td); + if (bt == NULL) + callout_reset_curcpu(&td->td_slpcallout, timo, + sleepq_timeout, td); + else + callout_reset_bt_on(&td->td_slpcallout, *bt, + sleepq_timeout, td, PCPU_GET(cpuid), 0); } /* Modified: projects/calloutng/sys/kern/sys_generic.c ============================================================================== --- projects/calloutng/sys/kern/sys_generic.c Sun Jun 17 19:16:31 2012 (r237201) +++ projects/calloutng/sys/kern/sys_generic.c Sun Jun 17 20:45:45 2012 (r237202) @@ -102,7 +102,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 *, struct bintime *, int); static void seltdclear(struct thread *); /* @@ -902,7 +902,8 @@ 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; + struct bintime abt, rbt; + struct timeval atv; int error, lf, ndu, timo; u_int nbufbytes, ncpbytes, ncpubytes, nfdbits; @@ -996,33 +997,34 @@ kern_select(struct thread *td, int nd, f if (tvp != NULL) { atv = *tvp; - if (itimerfix(&atv)) { + if (atv.tv_sec < 0 || atv.tv_usec < 0 || + atv.tv_usec >= 1000000) { error = EINVAL; goto done; } - getmicrouptime(&rtv); - timevaladd(&atv, &rtv); + binuptime(&rbt); + timeval2bintime(&atv, &abt); + bintime_add(&abt, &rbt); } else { - atv.tv_sec = 0; - atv.tv_usec = 0; + abt.sec = 0; + abt.frac = 0; } - timo = 0; 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, >=)) + if (abt.sec || abt.frac) { + binuptime(&rbt); + if (bintime_cmp(&rbt, &abt, >=)) break; - ttv = atv; - timevalsub(&ttv, &rtv); - timo = ttv.tv_sec > 24 * 60 * 60 ? - 24 * 60 * 60 * hz : tvtohz(&ttv); + error = seltdwait(td, &abt, 0); + } + else { + timo = 0; + error = seltdwait(td, NULL, timo); } - error = seltdwait(td, timo); if (error) break; error = selrescan(td, ibits, obits); @@ -1254,8 +1256,9 @@ sys_poll(td, uap) { struct pollfd *bits; struct pollfd smallbits[32]; - struct timeval atv, rtv, ttv; - int error = 0, timo; + struct bintime abt, rbt; + struct timeval atv; + int error, timo; u_int nfds; size_t ni; @@ -1273,33 +1276,33 @@ sys_poll(td, uap) if (uap->timeout != INFTIM) { atv.tv_sec = uap->timeout / 1000; atv.tv_usec = (uap->timeout % 1000) * 1000; - if (itimerfix(&atv)) { + if (atv.tv_sec < 0 || atv.tv_usec < 0 || + atv.tv_usec >= 1000000) { error = EINVAL; goto done; } - getmicrouptime(&rtv); - timevaladd(&atv, &rtv); + binuptime(&rbt); + timeval2bintime(&atv, &abt); + bintime_add(&abt, &rbt); } else { - atv.tv_sec = 0; - atv.tv_usec = 0; + abt.sec = 0; + abt.frac = 0; } - timo = 0; 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, >=)) + if (abt.sec || abt.frac) { + binuptime(&rbt); + if (bintime_cmp(&rbt, &abt, >=)) break; - ttv = atv; - timevalsub(&ttv, &rtv); - timo = ttv.tv_sec > 24 * 60 * 60 ? - 24 * 60 * 60 * hz : tvtohz(&ttv); + error = seltdwait(td, &abt, 0); + } else { + timo = 0; + error = seltdwait(td, NULL, timo); } - error = seltdwait(td, timo); if (error) break; error = pollrescan(td); @@ -1518,7 +1521,7 @@ selsocket(struct socket *so, int events, timo = ttv.tv_sec > 24 * 60 * 60 ? 24 * 60 * 60 * hz : tvtohz(&ttv); } - error = seltdwait(td, timo); + error = seltdwait(td, NULL, timo); seltdclear(td); if (error) break; @@ -1697,7 +1700,7 @@ out: } static int -seltdwait(struct thread *td, int timo) +seltdwait(struct thread *td, struct bintime *bt, int timo) { struct seltd *stp; int error; @@ -1716,9 +1719,11 @@ seltdwait(struct thread *td, int timo) mtx_unlock(&stp->st_mtx); return (0); } - if (timo > 0) + if (bt == NULL && timo > 0) error = cv_timedwait_sig(&stp->st_wait, &stp->st_mtx, timo); - else + else if (bt != NULL) + error = cv_timedwait_bt_sig(&stp->st_wait, &stp->st_mtx, *bt); + else error = cv_wait_sig(&stp->st_wait, &stp->st_mtx); mtx_unlock(&stp->st_mtx); Modified: projects/calloutng/sys/sys/condvar.h ============================================================================== --- projects/calloutng/sys/sys/condvar.h Sun Jun 17 19:16:31 2012 (r237201) +++ projects/calloutng/sys/sys/condvar.h Sun Jun 17 20:45:45 2012 (r237202) @@ -56,7 +56,8 @@ void _cv_wait(struct cv *cvp, struct loc void _cv_wait_unlock(struct cv *cvp, struct lock_object *lock); int _cv_wait_sig(struct cv *cvp, struct lock_object *lock); int _cv_timedwait(struct cv *cvp, struct lock_object *lock, int timo); -int _cv_timedwait_sig(struct cv *cvp, struct lock_object *lock, int timo); +int _cv_timedwait_sig(struct cv *cvp, struct lock_object *lock, + struct bintime *bt, int timo); void cv_signal(struct cv *cvp); void cv_broadcastpri(struct cv *cvp, int pri); @@ -70,7 +71,9 @@ void cv_broadcastpri(struct cv *cvp, int #define cv_timedwait(cvp, lock, timo) \ _cv_timedwait((cvp), &(lock)->lock_object, (timo)) #define cv_timedwait_sig(cvp, lock, timo) \ - _cv_timedwait_sig((cvp), &(lock)->lock_object, (timo)) + _cv_timedwait_sig((cvp), &(lock)->lock_object, (NULL), (timo)) +#define cv_timedwait_bt_sig(cvp, lock, bt) \ + _cv_timedwait_sig((cvp), &(lock)->lock_object, (&bt), (0)) #define cv_broadcast(cvp) cv_broadcastpri(cvp, 0) Modified: projects/calloutng/sys/sys/sleepqueue.h ============================================================================== --- projects/calloutng/sys/sys/sleepqueue.h Sun Jun 17 19:16:31 2012 (r237201) +++ projects/calloutng/sys/sys/sleepqueue.h Sun Jun 17 20:45:45 2012 (r237202) @@ -108,8 +108,11 @@ struct sleepqueue *sleepq_lookup(void *w void sleepq_release(void *wchan); void sleepq_remove(struct thread *td, void *wchan); int sleepq_signal(void *wchan, int flags, int pri, int queue); -void sleepq_set_timeout_bt(void *wchan, struct bintime bt); -void sleepq_set_timeout(void *wchan, int timo); +void _sleepq_set_timeout(void *wchan, struct bintime *bt, int timo); +#define sleepq_set_timeout(wchan, timo) \ + _sleepq_set_timeout((wchan), (NULL), (timo)) +#define sleepq_set_timeout_bt(wchan, bt) \ + _sleepq_set_timeout((wchan), (&bt), (0)) u_int sleepq_sleepcnt(void *wchan, int queue); int sleepq_timedwait(void *wchan, int pri); int sleepq_timedwait_sig(void *wchan, int pri);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201206172045.q5HKjj92031635>