Date: Fri, 8 Jun 2012 13:52:57 +0100 From: Attilio Rao <attilio@freebsd.org> To: Davide Italiano <davide@freebsd.org> Cc: svn-src-projects@freebsd.org, src-committers@freebsd.org Subject: Re: svn commit: r236744 - in projects/calloutng/sys: kern sys Message-ID: <CAJ-FndB7QPRnmqrwyR9ixF9Jom8n7P1OMs=rczOKhmRxt08m3g@mail.gmail.com> In-Reply-To: <201206081153.q58BrqG2056771@svn.freebsd.org> References: <201206081153.q58BrqG2056771@svn.freebsd.org>
index | next in thread | previous in thread | raw e-mail
2012/6/8 Davide Italiano <davide@freebsd.org>: > Author: davide > Date: Fri Jun 8 11:53:51 2012 > New Revision: 236744 > URL: http://svn.freebsd.org/changeset/base/236744 > > Log: > Add (experimentally) a function to the sleepqueue(9) KPI > sleepq_set_timeout_bt() in which the timeout may be specified in terms > of bintime rather than ticks, and which takes advantage of the new > precision capabilities of the callout subsystem. > > Modify the kern_nanosleep() function so that it may rely on > sleepq_set_timeout_bt() rather than tsleep(). > > Modified: > projects/calloutng/sys/kern/kern_time.c > projects/calloutng/sys/kern/subr_sleepqueue.c > projects/calloutng/sys/sys/sleepqueue.h > > Modified: projects/calloutng/sys/kern/kern_time.c > ============================================================================== > --- projects/calloutng/sys/kern/kern_time.c Fri Jun 8 11:40:30 2012 (r236743) > +++ projects/calloutng/sys/kern/kern_time.c Fri Jun 8 11:53:51 2012 (r236744) > @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); > #include <sys/resourcevar.h> > #include <sys/signalvar.h> > #include <sys/kernel.h> > +#include <sys/sleepqueue.h> > #include <sys/syscallsubr.h> > #include <sys/sysctl.h> > #include <sys/sysent.h> > @@ -352,37 +353,40 @@ static int nanowait; > int > kern_nanosleep(struct thread *td, struct timespec *rqt, struct timespec *rmt) > { > - struct timespec ts, ts2, ts3; > - struct timeval tv; > - int error; > + struct timespec ts; > + struct bintime bt, bt2, tmp; > + int catch = 0, error; > > if (rqt->tv_nsec < 0 || rqt->tv_nsec >= 1000000000) > return (EINVAL); > if (rqt->tv_sec < 0 || (rqt->tv_sec == 0 && rqt->tv_nsec == 0)) > return (0); > - getnanouptime(&ts); > - timespecadd(&ts, rqt); > - TIMESPEC_TO_TIMEVAL(&tv, rqt); > + binuptime(&bt); > + timespec2bintime(rqt, &tmp); > + bintime_add(&bt,&tmp); > for (;;) { > - error = tsleep(&nanowait, PWAIT | PCATCH, "nanslp", > - tvtohz(&tv)); > - getnanouptime(&ts2); > - if (error != EWOULDBLOCK) { > - if (error == ERESTART) > - error = EINTR; > - if (rmt != NULL) { > - timespecsub(&ts, &ts2); > - if (ts.tv_sec < 0) > - timespecclear(&ts); > - *rmt = ts; > - } > + sleepq_lock(&nanowait); > + sleepq_add(&nanowait, NULL, "nanslp", PWAIT | PCATCH, 0); > + sleepq_set_timeout_bt(&nanowait,bt); > + error = sleepq_timedwait_sig(&nanowait,catch); > + binuptime(&bt2); > + if (catch) { > + if (error != EWOULDBLOCK) { > + if (error == ERESTART) > + error = EINTR; > + if (rmt != NULL) { > + tmp = bt; > + bintime_sub(&tmp, &bt2); > + bintime2timespec(&tmp,&ts); > + if (ts.tv_sec < 0) > + timespecclear(&ts); > + *rmt = ts; > + } > return (error); > + } > } > - if (timespeccmp(&ts2, &ts, >=)) > + if (bintime_cmp(&bt2, &bt, >=)) > return (0); > - ts3 = ts; > - timespecsub(&ts3, &ts2); > - TIMESPEC_TO_TIMEVAL(&tv, &ts3); > } > } > > > Modified: projects/calloutng/sys/kern/subr_sleepqueue.c > ============================================================================== > --- projects/calloutng/sys/kern/subr_sleepqueue.c Fri Jun 8 11:40:30 2012 (r236743) > +++ projects/calloutng/sys/kern/subr_sleepqueue.c Fri Jun 8 11:53:51 2012 (r236744) > @@ -361,6 +361,22 @@ sleepq_add(void *wchan, struct lock_obje > * Sets a timeout that will remove the current thread from the specified > * sleep queue after timo ticks if the thread has not already been awakened. > */ > +void > +sleepq_set_timeout_bt(void *wchan, struct bintime bt) > +{ > + > + 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_bt_on(&td->td_slpcallout, bt, sleepq_timeout, td, PCPU_GET(cpuid)); > +} > + For this, I'd rather prefer that you patch sleepq_set_timeout() directly to be: void sleepq_set_timeout(void *wchan, int timo, struct bintime *bt); Then, if you pass a NULL ptr to bt the 'timo' is used, otherwise bt is given preference in the logic. You will need to patch the current few callers of sleepq_set_timo() to get NULL, but it is a small patch. I would really like that you do the same also in the callout KPI, possibly, because this avoids a lot of code duplication. Attilio -- Peace can only be achieved by understanding - A. Einsteinhelp
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAJ-FndB7QPRnmqrwyR9ixF9Jom8n7P1OMs=rczOKhmRxt08m3g>
