svn commit: r237202 - in projects/calloutng/sys: kern sys
Davide Italiano
davide at FreeBSD.org
Sun Jun 17 20:45:47 UTC 2012
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);
More information about the svn-src-projects
mailing list