svn commit: r198132 - head/tools/tools/netrate/netsend

Luigi Rizzo luigi at FreeBSD.org
Thu Oct 15 14:18:35 UTC 2009


Author: luigi
Date: Thu Oct 15 14:18:35 2009
New Revision: 198132
URL: http://svn.freebsd.org/changeset/base/198132

Log:
  A small change to avoid calling gettimeofday() too often
  (hardwired to once every 20us at most).
  
  I found out that on many machines round here, i could only get
  300-400kpps with netsend even on loopback and a 'deny' rule in
  the firewall, while reducing the number of calls to gettimeofday()
  brings the value to 900kpps and more.
  
  This code is just a quick fix for the problem. Of course it could be
  done better, with proper getopt() parsing and the like, but since
  this applies to the entire program i'll postpone that to when i have
  more time.
  
  Reviewed by:	rwatson
  MFC after:	1 month

Modified:
  head/tools/tools/netrate/netsend/netsend.c

Modified: head/tools/tools/netrate/netsend/netsend.c
==============================================================================
--- head/tools/tools/netrate/netsend/netsend.c	Thu Oct 15 13:34:45 2009	(r198131)
+++ head/tools/tools/netrate/netsend/netsend.c	Thu Oct 15 14:18:35 2009	(r198132)
@@ -124,6 +124,9 @@ timing_loop(int s, struct timespec inter
 	u_int32_t counter;
 	long finishtime;
 	long send_errors, send_calls;
+	/* do not call gettimeofday more than every 20us */
+	long minres_ns = 20000;
+	int ic, gettimeofday_cycles;
 
 	if (clock_getres(CLOCK_REALTIME, &tmptime) == -1) {
 		perror("clock_getres");
@@ -132,8 +135,15 @@ timing_loop(int s, struct timespec inter
 
 	if (timespec_ge(&tmptime, &interval))
 		fprintf(stderr,
-		    "warning: interval less than resolution (%jd.%09ld)\n",
+		    "warning: interval (%jd.%09ld) less than resolution (%jd.%09ld)\n",
+		    (intmax_t)interval.tv_sec, interval.tv_nsec,
 		    (intmax_t)tmptime.tv_sec, tmptime.tv_nsec);
+	if (tmptime.tv_nsec < minres_ns) {
+		gettimeofday_cycles = minres_ns/(tmptime.tv_nsec + 1);
+		fprintf(stderr,
+		    "calling time every %d cycles\n", gettimeofday_cycles);
+	} else
+		gettimeofday_cycles = 0;
 
 	if (clock_gettime(CLOCK_REALTIME, &starttime) == -1) {
 		perror("clock_gettime");
@@ -151,10 +161,14 @@ timing_loop(int s, struct timespec inter
 	send_errors = send_calls = 0;
 	counter = 0;
 	waited = 0;
+	ic = gettimeofday_cycles;
 	while (1) {
 		timespec_add(&nexttime, &interval);
-		if (wait_time(nexttime, &tmptime, &waited) == -1)
-			return (-1);
+		if (--ic <= 0) {
+			ic = gettimeofday_cycles;
+			if (wait_time(nexttime, &tmptime, &waited) == -1)
+				return (-1);
+		}
 		/*
 		 * We maintain and, if there's room, send a counter.  Note
 		 * that even if the error is purely local, we still increment
@@ -236,8 +250,9 @@ main(int argc, char *argv[])
 
 	/*
 	 * Specify an arbitrary limit.  It's exactly that, not selected by
-	 .* any particular strategy.  '0' is a special value meaning "blast",
+	 * any particular strategy.  '0' is a special value meaning "blast",
 	 * and avoids the cost of a timing loop.
+	 * XXX 0 is not actually implemented.
 	 */
 	rate = strtoul(argv[4], &dummy, 10);
 	if (rate < 1 || *dummy != '\0')


More information about the svn-src-head mailing list