xref: /dragonfly/test/sysperf/randread.c (revision cae2835b)
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 	    close(fd);
75 	    fd = open(av[1], O_RDONLY);
76 	    srandomdev();
77 	    for (;;) {
78 		long pos;
79 
80 		pos = random() ^ ((long)random() << 31);
81 		pos &= 0x7FFFFFFFFFFFFFFFLLU;
82 		pos = (pos % limit) & ~(off_t)(bytes - 1);
83 		lseek(fd, pos, 0);
84 		read(fd, buf, bytes);
85 		atomic_add_int(counterp, 1);
86 	    }
87 	}
88     }
89     start_timing();
90     sleep(1);
91     start_timing();
92     clast = *counterp;
93 
94     for (;;) {
95 	sleep(1);
96 	cnext = *counterp;
97 	cdelta = cnext - clast;
98 	clast = cnext;
99 	stop_timing(cdelta, "randread");
100     }
101     return 0;
102 }
103