svn commit: r236744 - in projects/calloutng/sys: kern sys

Davide Italiano davide at FreeBSD.org
Fri Jun 8 11:53:52 UTC 2012


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));
+}
+
 void
 sleepq_set_timeout(void *wchan, int timo)
 {

Modified: projects/calloutng/sys/sys/sleepqueue.h
==============================================================================
--- projects/calloutng/sys/sys/sleepqueue.h	Fri Jun  8 11:40:30 2012	(r236743)
+++ projects/calloutng/sys/sys/sleepqueue.h	Fri Jun  8 11:53:51 2012	(r236744)
@@ -108,6 +108,7 @@ 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);
 u_int	sleepq_sleepcnt(void *wchan, int queue);
 int	sleepq_timedwait(void *wchan, int pri);


More information about the svn-src-projects mailing list