From 86eb055238e5bc0606593a2688d4b634f635ba0b Mon Sep 17 00:00:00 2001 From: Michal Sojka Date: Thu, 10 Sep 2009 14:07:38 +0200 Subject: [PATCH] Added hackbench --- Makefile.omk | 3 + hackbench.c | 195 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 198 insertions(+) create mode 100644 hackbench.c diff --git a/Makefile.omk b/Makefile.omk index 038c8f7..d03639f 100644 --- a/Makefile.omk +++ b/Makefile.omk @@ -2,3 +2,6 @@ SUBDIRS += ocera-can/canvca/libvca/ SUBDIRS += ocera-can/lincan/ SUBDIRS += ocera-can/utils/ SUBDIRS += canping/src/ + +bin_PROGRAMS = hackbench +hackbench_SOURCES = hackbench.c diff --git a/hackbench.c b/hackbench.c new file mode 100644 index 0000000..8d98955 --- /dev/null +++ b/hackbench.c @@ -0,0 +1,195 @@ +/* Test groups of 20 processes spraying to 20 receivers */ +#include +#include +#include +#include +#include +#include +#include +#include + +#define DATASIZE 100 +static unsigned int loops = 100; +static int use_pipes = 0; + +static void barf(const char *msg) +{ + fprintf(stderr, "%s (error: %s)\n", msg, strerror(errno)); + exit(1); +} + +static void fdpair(int fds[2]) +{ + if (use_pipes) { + if (pipe(fds) == 0) + return; + } else { + if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0) + return; + } + barf("Creating fdpair"); +} + +/* Block until we're ready to go */ +static void ready(int ready_out, int wakefd) +{ + char dummy; + struct pollfd pollfd = { .fd = wakefd, .events = POLLIN }; + + /* Tell them we're ready. */ + if (write(ready_out, &dummy, 1) != 1) + barf("CLIENT: ready write"); + + /* Wait for "GO" signal */ + if (poll(&pollfd, 1, -1) != 1) + barf("poll"); +} + +/* Sender sprays loops messages down each file descriptor */ +static void sender(unsigned int num_fds, + int out_fd[num_fds], + int ready_out, + int wakefd) +{ + char data[DATASIZE]; + unsigned int i, j; + + ready(ready_out, wakefd); + + /* Now pump to every receiver. */ + for (i = 0; i < loops; i++) { + for (j = 0; j < num_fds; j++) { + int ret, done = 0; + + again: + ret = write(out_fd[j], data + done, sizeof(data)-done); + if (ret < 0) + barf("SENDER: write"); + done += ret; + if (done < sizeof(data)) + goto again; + } + } +} + +/* One receiver per fd */ +static void receiver(unsigned int num_packets, + int in_fd, + int ready_out, + int wakefd) +{ + unsigned int i; + + /* Wait for start... */ + ready(ready_out, wakefd); + + /* Receive them all */ + for (i = 0; i < num_packets; i++) { + char data[DATASIZE]; + int ret, done = 0; + + again: + ret = read(in_fd, data + done, DATASIZE - done); + if (ret < 0) + barf("SERVER: read"); + done += ret; + if (done < DATASIZE) + goto again; + } +} + +/* One group of senders and receivers */ +static unsigned int group(unsigned int num_fds, + int ready_out, + int wakefd) +{ + unsigned int i; + unsigned int out_fds[num_fds]; + + for (i = 0; i < num_fds; i++) { + int fds[2]; + + /* Create the pipe between client and server */ + fdpair(fds); + + /* Fork the receiver. */ + switch (fork()) { + case -1: barf("fork()"); + case 0: + close(fds[1]); + receiver(num_fds*loops, fds[0], ready_out, wakefd); + exit(0); + } + + out_fds[i] = fds[1]; + close(fds[0]); + } + + /* Now we have all the fds, fork the senders */ + for (i = 0; i < num_fds; i++) { + switch (fork()) { + case -1: barf("fork()"); + case 0: + sender(num_fds, out_fds, ready_out, wakefd); + exit(0); + } + } + + /* Close the fds we have left */ + for (i = 0; i < num_fds; i++) + close(out_fds[i]); + + /* Return number of children to reap */ + return num_fds * 2; +} + +int main(int argc, char *argv[]) +{ + unsigned int i, num_groups, total_children; + struct timeval start, stop, diff; + unsigned int num_fds = 20; + int readyfds[2], wakefds[2]; + char dummy; + + if (argv[1] && strcmp(argv[1], "-pipe") == 0) { + use_pipes = 1; + argc--; + argv++; + } + + if (argc != 2 || (num_groups = atoi(argv[1])) == 0) + barf("Usage: hackbench [-pipe] \n"); + + fdpair(readyfds); + fdpair(wakefds); + + total_children = 0; + for (i = 0; i < num_groups; i++) + total_children += group(num_fds, readyfds[1], wakefds[0]); + + /* Wait for everyone to be ready */ + for (i = 0; i < total_children; i++) + if (read(readyfds[0], &dummy, 1) != 1) + barf("Reading for readyfds"); + + gettimeofday(&start, NULL); + + /* Kick them off */ + if (write(wakefds[1], &dummy, 1) != 1) + barf("Writing to start them"); + + /* Reap them all */ + for (i = 0; i < total_children; i++) { + int status; + wait(&status); + if (!WIFEXITED(status)) + exit(1); + } + + gettimeofday(&stop, NULL); + + /* Print time... */ + timersub(&stop, &start, &diff); + printf("Time: %lu.%03lu\n", diff.tv_sec, diff.tv_usec/1000); + exit(0); +} -- 2.39.2