test - Add random seek/read program
[dragonfly.git] / test / sysperf / randread.c
1
2 #include <sys/types.h>
3 #include <sys/stat.h>
4 #include <sys/file.h>
5 #include <sys/errno.h>
6 #include <sys/wait.h>
7 #include <string.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <machine/atomic.h>
12 #include "blib.h"
13
14 int
15 main(int ac, char **av)
16 {
17     char *buf;
18     size_t bytes = 512;
19     off_t limit;
20     int fd;
21     int i;
22     int nprocs = 32;
23     double range = 90.0;
24     volatile int *counterp;
25     int clast;
26     int cnext;
27     int cdelta;
28
29     if (ac < 2 || ac > 5) {
30         fprintf(stderr, "%s <device> [bufsize:512 [range%:90 [nprocs:32]]]\n",
31                 av[0]);
32         exit (1);
33     }
34
35     if (ac >= 3) {
36         bytes = (size_t)strtoul(av[2], NULL, 0);
37         if (bytes < 512 || (bytes ^ (bytes - 1)) != ((bytes << 1) - 1)) {
38             fprintf(stderr, "bytes must be a power of 2 >= 512\n");
39             exit (1);
40         }
41     }
42     buf = malloc(bytes);
43
44     if (ac >= 4) {
45         range = strtod(av[3], NULL);
46     }
47
48     if (ac >= 5) {
49         nprocs = strtol(av[4], NULL, 0);
50         if (nprocs < 0 || nprocs > 512) {
51             fprintf(stderr, "absurd nprocs (%d)\n", nprocs);
52             exit(1);
53         }
54     }
55
56     fd = open(av[1], O_RDONLY);
57     if (fd < 0) {
58         fprintf(stderr, "open %s: %s\n", av[1], strerror(errno));
59         exit (1);
60     }
61
62     lseek(fd, 0L, 2);
63     limit = lseek(fd, 0L, 1);
64     limit = (off_t)((double)limit * range / 100.0);
65     limit &= ~(off_t)(bytes - 1);
66     printf("device %s bufsize %zd limit %4.3fGB nprocs %d\n",
67         av[1], bytes, (double)limit / (1024.0*1024.0*1024.0), nprocs);
68
69     counterp = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE,
70                     MAP_SHARED|MAP_ANON, -1, 0);
71
72     for (i = 0; i < nprocs; ++i) {
73         if (fork() == 0) {
74             srandomdev();
75             for (;;) {
76                 long pos = (random() % limit) & ~(off_t)(bytes - 1);
77                 lseek(fd, pos, 0);
78                 read(fd, buf, bytes);
79                 atomic_add_int(counterp, 1);
80             }
81         }
82     }
83     start_timing();
84     sleep(1);
85     start_timing();
86     clast = *counterp;
87
88     for (;;) {
89         sleep(1);
90         cnext = *counterp;
91         cdelta = cnext - clast;
92         clast = cnext;
93         stop_timing(cdelta, "randread");
94     }
95     return 0;
96 }