diff options
author | David Sommerseth <davids@redhat.com> | 2010-02-17 19:08:44 +0100 |
---|---|---|
committer | David Sommerseth <davids@redhat.com> | 2010-02-17 19:08:44 +0100 |
commit | f79ca322df15aa258866ccaacacd463c47ec0ca5 (patch) | |
tree | 8ee473010a335672731a4c9a0d4e4b84ed7174aa | |
parent | 73d48f4e04684a376b41525bfed030b7671f03f7 (diff) | |
download | rt-tests-f79ca322df15aa258866ccaacacd463c47ec0ca5.tar.gz |
Imported hackbench from rteval-1.18 (rteval-loads-1.0.1)
Signed-off-by: David Sommerseth <davids@redhat.com>
-rw-r--r-- | src/hackbench/Makefile | 2 | ||||
-rw-r--r-- | src/hackbench/hackbench.c | 195 | ||||
-rw-r--r-- | src/hackbench/runit.pl | 123 |
3 files changed, 320 insertions, 0 deletions
diff --git a/src/hackbench/Makefile b/src/hackbench/Makefile new file mode 100644 index 0000000..3465852 --- /dev/null +++ b/src/hackbench/Makefile @@ -0,0 +1,2 @@ +hackbench: hackbench.c + $(CC) $(CFLAGS) -o hackbench hackbench.c diff --git a/src/hackbench/hackbench.c b/src/hackbench/hackbench.c new file mode 100644 index 0000000..8d98955 --- /dev/null +++ b/src/hackbench/hackbench.c @@ -0,0 +1,195 @@ +/* Test groups of 20 processes spraying to 20 receivers */ +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/wait.h> +#include <sys/time.h> +#include <sys/poll.h> + +#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] <num groups>\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); +} diff --git a/src/hackbench/runit.pl b/src/hackbench/runit.pl new file mode 100644 index 0000000..6e46b7b --- /dev/null +++ b/src/hackbench/runit.pl @@ -0,0 +1,123 @@ +#!/usr/bin/perl -w + +use Env; + +if ( ! $STP_CLIENT_API ) +{ + print "No STP environment. Exiting.\n"; + exit -1; +} + +# This will take two optional arguments: +# STEP: Min value and The step to use +# MAX: The maximum # of groups to reach in testing + +if ($#ARGV == 1) +{ + $STEP = $ARGV[0]; + $MAX = $ARGV[1]; +} else { + $STEP = 20; + $MAX = 100; +} + +# We suggest that unless you want to build in package listings for each possible +# target OS, you should have a script ready to automate the build process. + +print "\nWelcome to the hackbench test\n\n"; +print "---Making the binaries (via make clean all)---\n"; +print `rm -rf bin`; +print `tar -zxf hackbench_bin.tar.gz`; +chdir "bin"; +print `make clean all 1> /dev/null`; +print "---Done---\n\n"; + +# Create final index.html +open FHI, ">$WRAP_HOME/index.html"; +open FHO, "<$RESULTS_HEADER"; +while(<FHO>){ + print FHI; +} +close FHO; +open FHO, "<$WRAP_HOME/index.body"; +while(<FHO>){ + print FHI; +} +close FHO; +open FHO, "<$RESULTS_FOOTER"; +while(<FHO>){ + print FHI; +} +close FHI; +close FHO; + +open (FILE, ">>$RESULTS/data") || die "cannot append to results file"; +print FILE "# Hackbench Results\n"; +print FILE "# -------------------------------\n"; +print FILE "# Processes | Ave Time(sec)\n"; +print FILE "# -------------------------------\n"; + +# REMEMBER, any output form this file is sent as an email to the user, make sure it's +# short, informative and not filled with binary error spews. + +print "========================\n"; +print "Executing hackbench runs\n"; +print "========================\n\n"; + +# This is a basic run with simple values + +# The system makes this directory now +#system "rm -rf $RESULTS"; +#mkdir "$RESULTS"; + +@times = (); + +print "Running with $STEP to $MAX groups, with step $STEP\n"; + +system ("/usr/bin/stp_timeout.sh 2h hackbench &"); + +system ("stp_profile 'Test set-up complete.'"); + +for ($numgr = $STEP; $numgr <= $MAX; $numgr += $STEP ) +{ + print "Running with $numgr groups"; + + for ($run = 0; $run < 5; $run++) + { + + if ( `./hackbench $numgr` =~ m/Time: ([0-9.]+)/ ) { + $time = $1; + } + push(@times, $time); + print "."; + } + + $ave = 0; + foreach $time (@times) + { + $ave += $time; + } + $ave = $ave / scalar(@times); + print " Average $ave s\n"; + + print FILE "$numgr $ave\n"; +} +close FILE; + +system ("stp_profile 'Run test.'"); + +open FHO, "<$RESULTS/data"; +open FHI, ">>$RESULTS_EMAIL"; +while (<FHO>){ + print FHI; +} +close FHO; +close FHI; + +# Make the plot +system "cp -a $WRAP_HOME/graph.cfg $RESULTS/"; +chdir $RESULTS; +chmod 0755, 'graph.cfg'; +system ("$RESULTS/graph.cfg"); + +exit; |