test - Add random seek/read program
authorMatthew Dillon <dillon@apollo.backplane.com>
Wed, 13 Apr 2011 16:33:25 +0000 (09:33 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Wed, 13 Apr 2011 16:42:06 +0000 (09:42 -0700)
* Add program which reads a random 512 byte block in a device or file
  with 32 concurrent accessors and displays the results.

* make /tmp/rr1 from /usr/src/test/sysperf

test/sysperf/Makefile
test/sysperf/blib.c
test/sysperf/randread.c [new file with mode: 0644]

index 752a2f3..485f4e8 100644 (file)
@@ -13,7 +13,8 @@ TARGETS=/tmp/sc1 /tmp/sc2 /tmp/sc3 /tmp/sc4 /tmp/sc5 \
        /tmp/upc1 \
        /tmp/exec1 /tmp/exec2 \
        /tmp/mem1 /tmp/mem2 \
-       /tmp/cld1
+       /tmp/cld1 \
+       /tmp/rr1
 
 .if defined(NO_OPTIMIZE)
 COPTFLAGS= -O
@@ -120,5 +121,8 @@ all:        $(TARGETS)
 /tmp/read1: read1.c blib.c
        $(CC) $(CFLAGS) read1.c blib.c -o /tmp/read1
 
+/tmp/rr1: randread.c blib.c
+       $(CC) $(CFLAGS) randread.c blib.c -o /tmp/rr1
+
 clean:
        rm -f $(TARGETS)
index cf09cad..c668a79 100644 (file)
@@ -41,6 +41,9 @@ stop_timing(long long count, const char *ctl, ...)
        count,
        (double)us / (double)count
     );
+
+    tv1 = tv2;
+
     return(0);
 }
 
diff --git a/test/sysperf/randread.c b/test/sysperf/randread.c
new file mode 100644 (file)
index 0000000..f0ce61b
--- /dev/null
@@ -0,0 +1,96 @@
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <sys/errno.h>
+#include <sys/wait.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <machine/atomic.h>
+#include "blib.h"
+
+int
+main(int ac, char **av)
+{
+    char *buf;
+    size_t bytes = 512;
+    off_t limit;
+    int fd;
+    int i;
+    int nprocs = 32;
+    double range = 90.0;
+    volatile int *counterp;
+    int clast;
+    int cnext;
+    int cdelta;
+
+    if (ac < 2 || ac > 5) {
+       fprintf(stderr, "%s <device> [bufsize:512 [range%:90 [nprocs:32]]]\n",
+               av[0]);
+       exit (1);
+    }
+
+    if (ac >= 3) {
+       bytes = (size_t)strtoul(av[2], NULL, 0);
+       if (bytes < 512 || (bytes ^ (bytes - 1)) != ((bytes << 1) - 1)) {
+           fprintf(stderr, "bytes must be a power of 2 >= 512\n");
+           exit (1);
+       }
+    }
+    buf = malloc(bytes);
+
+    if (ac >= 4) {
+       range = strtod(av[3], NULL);
+    }
+
+    if (ac >= 5) {
+       nprocs = strtol(av[4], NULL, 0);
+       if (nprocs < 0 || nprocs > 512) {
+           fprintf(stderr, "absurd nprocs (%d)\n", nprocs);
+           exit(1);
+       }
+    }
+
+    fd = open(av[1], O_RDONLY);
+    if (fd < 0) {
+       fprintf(stderr, "open %s: %s\n", av[1], strerror(errno));
+       exit (1);
+    }
+
+    lseek(fd, 0L, 2);
+    limit = lseek(fd, 0L, 1);
+    limit = (off_t)((double)limit * range / 100.0);
+    limit &= ~(off_t)(bytes - 1);
+    printf("device %s bufsize %zd limit %4.3fGB nprocs %d\n",
+       av[1], bytes, (double)limit / (1024.0*1024.0*1024.0), nprocs);
+
+    counterp = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE,
+                   MAP_SHARED|MAP_ANON, -1, 0);
+
+    for (i = 0; i < nprocs; ++i) {
+       if (fork() == 0) {
+           srandomdev();
+           for (;;) {
+               long pos = (random() % limit) & ~(off_t)(bytes - 1);
+               lseek(fd, pos, 0);
+               read(fd, buf, bytes);
+               atomic_add_int(counterp, 1);
+           }
+       }
+    }
+    start_timing();
+    sleep(1);
+    start_timing();
+    clast = *counterp;
+
+    for (;;) {
+       sleep(1);
+       cnext = *counterp;
+       cdelta = cnext - clast;
+       clast = cnext;
+       stop_timing(cdelta, "randread");
+    }
+    return 0;
+}