svn commit: r247797 - head/sys/kern

Davide Italiano davide at FreeBSD.org
Mon Mar 4 15:57:41 UTC 2013


Author: davide
Date: Mon Mar  4 15:57:41 2013
New Revision: 247797
URL: http://svnweb.freebsd.org/changeset/base/247797

Log:
  MFcalloutng:
  kern_nanosleep() is now converted to use tsleep_sbt(). With this change
  nanosleep() and usleep() can handle sub-tick precision for timeouts.
  Also, try to help coalesce of events passing as argument to tsleep_bt()
  a precision value calculated as a percentage of the sleep time.
  This percentage is default 5%, but it can tuned according to users
  need via the sysctl interface.
  
  Sponsored by:	Google Summer of Code 2012, iXsystems inc.
  Tested by:	flo, marius, ian, markj, Fabian Keil

Modified:
  head/sys/kern/kern_time.c

Modified: head/sys/kern/kern_time.c
==============================================================================
--- head/sys/kern/kern_time.c	Mon Mar  4 15:34:59 2013	(r247796)
+++ head/sys/kern/kern_time.c	Mon Mar  4 15:57:41 2013	(r247797)
@@ -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>
@@ -481,38 +482,37 @@ static int nanowait;
 int
 kern_nanosleep(struct thread *td, struct timespec *rqt, struct timespec *rmt)
 {
-	struct timespec ts, ts2, ts3;
-	struct timeval tv;
+	struct timespec ts;
+	sbintime_t sbt, sbtt, prec, tmp;
 	int 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);
-	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;
-			}
-			return (error);
+	tmp = tstosbt(*rqt);
+	prec = tmp;
+	prec >>= tc_precexp;
+	if (TIMESEL(&sbt, tmp))
+		sbt += tc_tick_sbt;
+	sbt += tmp;
+	error = tsleep_sbt(&nanowait, PWAIT | PCATCH, "nanslp", sbt, prec,
+	    C_ABSOLUTE);
+	if (error != EWOULDBLOCK) {
+		if (error == ERESTART)
+			error = EINTR;
+		TIMESEL(&sbtt, tmp);
+		if (rmt != NULL) {
+			ts = sbttots(sbt - sbtt);
+			if (ts.tv_sec < 0)
+				timespecclear(&ts);
+			*rmt = ts;
 		}
-		if (timespeccmp(&ts2, &ts, >=))
+		if (sbtt >= sbt)
 			return (0);
-		ts3 = ts;
-		timespecsub(&ts3, &ts2);
-		TIMESPEC_TO_TIMEVAL(&tv, &ts3);
+		return (error);
 	}
+	return (0);
 }
 
 #ifndef _SYS_SYSPROTO_H_


More information about the svn-src-all mailing list