Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 4 Mar 2013 15:57:41 +0000 (UTC)
From:      Davide Italiano <davide@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r247797 - head/sys/kern
Message-ID:  <201303041557.r24Fvfvx010386@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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_



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201303041557.r24Fvfvx010386>