From 26b338bbb6d10ca19eabee2bcb0bdf9ef82bca63 Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Sat, 19 Nov 2016 16:28:11 +0100 Subject: tools: Use busy waiting in operf Using nanosleep in between sending SDUs is not accurate enough when sending thousands of SDUs per second. The --sleep option is added for lowering CPU consumption in low bandwidth tests. --- src/tools/operf/operf.c | 5 +++++ src/tools/operf/operf_client.c | 23 +++++++++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) (limited to 'src/tools/operf') diff --git a/src/tools/operf/operf.c b/src/tools/operf/operf.c index b52109cf..46dfc14d 100644 --- a/src/tools/operf/operf.c +++ b/src/tools/operf/operf.c @@ -41,6 +41,7 @@ struct c { int size; long rate; bool flood; + bool sleep; int duration; size_t sent; @@ -81,6 +82,7 @@ static void usage(void) " -r, --rate Rate (b/s)\n" " -s, --size Payload size (B, default 1500)\n" " -f, --flood Send SDUs as fast as possible\n" + " --sleep Sleep in between sending SDUs\n" " --help Display this help text and exit\n"); } @@ -100,6 +102,7 @@ int main(int argc, char ** argv) server.timeout = 1000; /* ms */ client.rate = 1000000; client.flood = false; + client.sleep = false; while (argc > 0) { if (strcmp(*argv, "-n") == 0 || @@ -127,6 +130,8 @@ int main(int argc, char ** argv) } else if (strcmp(*argv, "-f") == 0 || strcmp(*argv, "--flood") == 0) { client.flood = true; + } else if (strcmp(*argv, "--sleep") == 0) { + client.sleep = true; } else if (strcmp(*argv, "-l") == 0 || strcmp(*argv, "--listen") == 0) { serv = true; diff --git a/src/tools/operf/operf_client.c b/src/tools/operf/operf_client.c index 1f6226d4..902a7b41 100644 --- a/src/tools/operf/operf_client.c +++ b/src/tools/operf/operf_client.c @@ -36,6 +36,17 @@ #include #include +static void busy_wait_until(const struct timespec * deadline) +{ + struct timespec now; + clock_gettime(CLOCK_REALTIME, &now); + while (now.tv_sec < deadline->tv_sec) + clock_gettime(CLOCK_REALTIME, &now); + while (now.tv_sec == deadline->tv_sec + && now.tv_nsec < deadline->tv_nsec) + clock_gettime(CLOCK_REALTIME, &now); +} + void shutdown_client(int signo, siginfo_t * info, void * c) { (void) info; @@ -85,6 +96,7 @@ void * writer(void * o) struct timespec now; struct timespec start; struct timespec intv = {(gap / BILLION), gap % BILLION}; + struct timespec end = {0, 0}; char * buf = malloc(client.size); if (buf == NULL) @@ -123,6 +135,9 @@ void * writer(void * o) } } else { while (ts_diff_ms(&start, &now) < client.duration) { + clock_gettime(CLOCK_REALTIME, &now); + ts_add(&now, &intv, &end); + if (flow_write(*fdp, buf, client.size) == -1) { printf("Failed to send SDU.\n"); flow_dealloc(*fdp); @@ -131,10 +146,10 @@ void * writer(void * o) } ++client.sent; - - nanosleep(&intv, NULL); - - clock_gettime(CLOCK_REALTIME, &now); + if (client.sleep) + nanosleep(&intv, NULL); + else + busy_wait_until(&end); } } -- cgit v1.2.3