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