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