tuxload - Enhace tuxload a bit.
[dragonfly.git] / test / stress / tuxload.c
CommitLineData
d921454f
MD
1/*
2 * TUXLOAD.C
3 *
4 * (c)Copyright 2012 Antonio Huete Jimenez <tuxillo@quantumachine.net>,
5 * this code is hereby placed in the public domain.
6 *
7 * As a safety the directory 'tmpfiles/' must exist. This program will
8 * create 500 x 8MB files in tmpfiles/*, memory map the files MAP_SHARED,
9 * R+W, make random modifications, and msync() in a loop.
10 *
11 * The purpose is to stress the VM system.
1923035e 12 *
d921454f
MD
13 */
14#include <stdio.h>
15#include <unistd.h>
16#include <fcntl.h>
17#include <stdlib.h>
18#include <sys/mman.h>
19#include <sys/stat.h>
20#include <err.h>
1923035e 21#include <errno.h>
d921454f
MD
22
23static void randomfill(int fd);
1923035e
AHJ
24static int mmap01(void *);
25static int mmap02(void *);
26static int build_files(void);
d921454f 27
1923035e
AHJ
28int opt_verbose;
29int opt_testno;
30int opt_nofiles;
31int opt_mbfile;
32int opt_count;
33int fliparg;
34
35int *fd;
36struct stat *st;
37char **pp;
38
39static const struct test {
40 char testdesc[128];
41 int (*testfn)(void *);
42} testlist[] = {
43 { "mmap01 - Massive mmap / msync (flushing all pages)", mmap01 },
44 { "mmap02 - Massive mmap / msync (flushing only specified pages)", mmap02 },
45 { "", NULL }
46};
47
48static int
49mmap01(void *arg)
d921454f 50{
1923035e
AHJ
51 int i;
52 int *bug = arg;
53 long jump;
54 size_t size, len;
d921454f 55
1923035e
AHJ
56 if ((build_files()) != 0)
57 err(1, "Failed to create the files");
d921454f 58
1923035e
AHJ
59 if (opt_verbose)
60 printf("\n");
e3ba86ed 61
1923035e 62 for (i = 0; i < opt_nofiles; i++) {
d921454f 63
1923035e
AHJ
64 if (opt_verbose) {
65 fflush(stdout);
66 fprintf(stdout, "\rDoing mmap() + msync() [%d/%d] ", i+1, opt_nofiles);
67 }
d921454f 68 size = st[i].st_size;
1923035e
AHJ
69 pp[i] = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd[i], 0);
70 if (pp[i] == MAP_FAILED)
d921454f
MD
71 err(1, "mmap");
72
73 for (jump = 0; jump < size; jump += 65535) {
1923035e 74 pp[i][jump] = jump + i;
d921454f 75 }
45c97380 76
1923035e
AHJ
77 if (fliparg)
78 len = MS_SYNC;
79 else
80 len = 0;
81
82 if ((msync(pp[i], len, MS_SYNC)) == -1) {
83 printf("fd %d %p\n", fd[i], pp[i]);
d921454f
MD
84 err(1, "msync");
85
86 }
87 }
1923035e
AHJ
88 printf("\n");
89
90 return 0;
91}
92
93static int
94mmap02(void *arg)
95{
96 fliparg = 1;
97 mmap01(&fliparg);
98
99 return 0;
100}
101
102static void
103usage(void)
104{
105 int i;
106 const struct test *tp;
107
108 printf("tuxload: [-v] [-c count] [-m megs_per_file] [-n no_of_files] [-t test_to_run] \n"
109 "Available tests: \n");
110
111 for (tp = testlist; tp->testfn != NULL; tp++)
112 printf("\t%s\n", tp->testdesc);
113 exit(1);
114}
115
116int
117main(int argc, char *argv[])
118{
119 int forever;
120 char c;
121
122 opt_verbose = opt_testno = 0;
123 opt_nofiles = 500;
124 opt_mbfile = 8;
125 opt_count = 1;
126 fliparg = 0;
127 forever = 0;
128
129 while ((c = getopt(argc, argv, "n:t:m:c:v")) != -1) {
130 switch(c) {
131 case 'v':
132 opt_verbose++;
133 break;
134 case 'n':
135 opt_nofiles = (int)strtol(optarg, NULL, 0);
136 break;
137 case 't':
138 opt_testno = (int)strtol(optarg, NULL, 0);
139 opt_testno--;
140 break;
141 case 'm':
142 opt_mbfile = (int)strtol(optarg, NULL, 0);
143 break;
144 case 'c':
145 opt_count = (int)strtol(optarg, NULL, 0);
146 if (opt_count == 0)
147 forever++;
148 break;
149 default:
150 usage();
151 ;
152 }
153 }
154 argc -= optind;
155 argv += optind;
156
157 if (argc != 0)
158 usage();
159
160 st = malloc(opt_nofiles * sizeof(*st));
161 fd = malloc(opt_nofiles * sizeof(*fd));
162 pp = malloc(opt_nofiles * sizeof(*pp));
163
164 while (opt_count-- || forever)
165 testlist[opt_testno].testfn(0);
166
d921454f 167 return 0;
d921454f
MD
168}
169
1923035e
AHJ
170static int
171build_files(void)
172{
173 char name[128];
174 int i;
175 int error;
176
177 for (i = 0, error = 0; i < opt_nofiles; i++) {
178 snprintf(name, 128, "tmpfiles/file%d", i);
179 if ((fd[i] = open(name, O_RDWR)) < 1) {
180 if ((fd[i] = open(name, O_RDWR | O_CREAT, 0644)) < 1) {
181 error = errno;
182 break;
183 }
184 randomfill(fd[i]);
185 }
186 if ((fstat(fd[i], &st[i])) == -1) {
187 error = errno;
188 break;
189 }
190 if (opt_verbose) {
191 fprintf(stdout, "\rFile creation, random data filled [%d/%d] ", i+1, opt_nofiles);
192 fflush(stdout);
193 }
194 }
195
196 return error;
197}
198
d921454f
MD
199static void
200randomfill(int fd)
201{
202 char buf[32768];
1923035e 203 long tot;
d921454f
MD
204 int i;
205
206 srandomdev();
1923035e 207 tot = opt_mbfile * 1024L;
d921454f
MD
208 for (i = 0; i < 32768; ++i)
209 buf[i] = random();
1923035e 210 for (i = 0; i < tot; i += 32) /* 8MB by default */
d921454f
MD
211 write(fd, buf, 32768);
212 fsync(fd);
213 lseek(fd, 0L, 0);
214}