summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2018-01-05 17:29:27 +0000
committerRoy Marples <roy@marples.name>2018-01-05 17:29:27 +0000
commita831c3f16b32eefc12a6e561b3c62ae15bee2609 (patch)
tree62e27019b974d5934eb2450100b0b109b78a6b14 /tests
parent28f4254167ce452afc3f48140126a7e4ad0439fb (diff)
downloaddhcpcd-a831c3f16b32eefc12a6e561b3c62ae15bee2609.tar.xz
eloop-bench: fix reading the last write
The last write was never read from the pipe in the run, so many runs filled the kernel buffer causing an error which was not seen because the pipe was blocking. Set the pipes to non blocking and improve the exit conditions, also ensuring the bench returns any error back. While here add more timings and run critera. Thanks to Christos Zoulas for helping.
Diffstat (limited to 'tests')
-rw-r--r--tests/eloop-bench/eloop-bench.c84
1 files changed, 51 insertions, 33 deletions
diff --git a/tests/eloop-bench/eloop-bench.c b/tests/eloop-bench/eloop-bench.c
index e7fd5a73..813fedf1 100644
--- a/tests/eloop-bench/eloop-bench.c
+++ b/tests/eloop-bench/eloop-bench.c
@@ -26,7 +26,9 @@
*/
#include <sys/resource.h>
+
#include <err.h>
+#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
@@ -59,38 +61,37 @@ static void
read_cb(void *arg)
{
struct pipe *p = arg;
- unsigned char c;
- ssize_t l;
+ unsigned char buf[1];
- l = read(p->fd[0], &c, sizeof(c));
- if (l == -1)
+ if (read(p->fd[0], buf, 1) != 1) {
+ warn("%s: read", __func__);
bad++;
- else
- good += (size_t)l;
- if (writes) {
- p = (struct pipe *)arg;
- l = write(p->fd[1], "e", 1);
- if (l != 1)
+ } else
+ good++;
+
+ if (writes != 0) {
+ writes--;
+ if (write(p->fd[1], "e", 1) != 1) {
+ warn("%s: write", __func__);
bad++;
- else {
- writes -= (size_t)l;
- fired += (size_t)l;
- }
+ } else
+ fired++;
}
- if (writes == 0) {
- if (good == fired)
- eloop_exit(e, EXIT_SUCCESS);
+ if (writes == 0 && fired == good) {
+ //printf("fired %zu, good %zu, bad %zu\n", fired, good, bad);
+ eloop_exit(e, good == fired && bad == 0 ?
+ EXIT_SUCCESS : EXIT_FAILURE);
}
}
-static struct timespec *
-runone(void)
+static int
+runone(struct timespec *t)
{
size_t i;
struct pipe *p;
- static struct timespec _ts;
struct timespec ts, te;
+ int result;
writes = nwrites;
fired = good = 0;
@@ -98,28 +99,27 @@ runone(void)
for (i = 0, p = pipes; i < nactive; i++, p++) {
if (write(p->fd[1], "e", 1) != 1)
err(EXIT_FAILURE, "send");
+ writes--;
+ fired++;
}
if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
err(EXIT_FAILURE, "clock_gettime");
- (void) eloop_start(e, NULL);
+ result = eloop_start(e, NULL);
if (clock_gettime(CLOCK_MONOTONIC, &te) == -1)
err(EXIT_FAILURE, "clock_gettime");
- timespecsub(&te, &ts, &_ts);
- return &_ts;
+ timespecsub(&te, &ts, t);
+ return result;
}
int
main(int argc, char **argv)
{
- int c;
+ int c, result, exit_code;
size_t i, nruns = 25;
struct pipe *p;
- struct timespec *ts;
-
- if ((e = eloop_new()) == NULL)
- err(EXIT_FAILURE, "eloop_init");
+ struct timespec ts, te, t;
while ((c = getopt(argc, argv, "a:n:r:w:")) != -1) {
switch (c) {
@@ -140,6 +140,12 @@ main(int argc, char **argv)
}
}
+ if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
+ err(EXIT_FAILURE, "clock_gettime");
+
+ if ((e = eloop_new()) == NULL)
+ err(EXIT_FAILURE, "eloop_init");
+
if (nactive > npipes)
nactive = npipes;
@@ -148,19 +154,31 @@ main(int argc, char **argv)
err(EXIT_FAILURE, "malloc");
for (i = 0, p = pipes; i < npipes; i++, p++) {
- if (pipe(p->fd) == -1)
+ if (pipe2(p->fd, O_CLOEXEC | O_NONBLOCK) == -1)
err(EXIT_FAILURE, "pipe");
if (eloop_event_add(e, p->fd[0], read_cb, p) == -1)
err(EXIT_FAILURE, "eloop_event_add");
}
+ printf("active = %zu, pipes = %zu, runs = %zu, writes = %zu\n",
+ nactive, npipes, nruns, nwrites);
+
+ exit_code = EXIT_SUCCESS;
for (i = 0; i < nruns; i++) {
- if ((ts = runone()) == NULL)
- err(EXIT_FAILURE, "runone");
- printf("%lld.%.9ld\n", (long long)ts->tv_sec, ts->tv_nsec);
+ result = runone(&t);
+ if (result != EXIT_SUCCESS)
+ exit_code = result;
+ printf("run %zu took %lld.%.9ld seconds, result %d\n",
+ i + 1, (long long)t.tv_sec, t.tv_nsec, result);
}
eloop_free(e);
free(pipes);
- exit(0);
+
+ if (clock_gettime(CLOCK_MONOTONIC, &te) == -1)
+ err(EXIT_FAILURE, "clock_gettime");
+ timespecsub(&te, &ts, &t);
+ printf("total %lld.%.9ld seconds, result %d\n",
+ (long long)t.tv_sec, t.tv_nsec, exit_code);
+ exit(exit_code);
}