summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorluigi <luigi@FreeBSD.org>2009-10-15 14:18:35 +0000
committerluigi <luigi@FreeBSD.org>2009-10-15 14:18:35 +0000
commitc369f72e79562af70cc2ac640a8099842519403d (patch)
tree5975ea7c59ac3207b8f13198a13dfc3426b47d39 /tools
parentf88b32f139a5e8b2b91b99937b72aa0fab472bf4 (diff)
downloadFreeBSD-src-c369f72e79562af70cc2ac640a8099842519403d.zip
FreeBSD-src-c369f72e79562af70cc2ac640a8099842519403d.tar.gz
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
Diffstat (limited to 'tools')
-rw-r--r--tools/tools/netrate/netsend/netsend.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/tools/tools/netrate/netsend/netsend.c b/tools/tools/netrate/netsend/netsend.c
index 8a335b6..b47c509 100644
--- a/tools/tools/netrate/netsend/netsend.c
+++ b/tools/tools/netrate/netsend/netsend.c
@@ -124,6 +124,9 @@ timing_loop(int s, struct timespec interval, long duration, u_char *packet,
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 interval, long duration, u_char *packet,
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 interval, long duration, u_char *packet,
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')
OpenPOWER on IntegriCloud