522b93da7d0100cfe2aa7eec012d70fae1669755
[dragonfly.git] / test / stress / tuxload.c
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.
12  */
13 #include <stdio.h>
14 #include <unistd.h>
15 #include <fcntl.h>
16 #include <stdlib.h>
17 #include <sys/mman.h>
18 #include <sys/stat.h>
19 #include <err.h>
20
21 #define NFILES 500
22
23 static void randomfill(int fd);
24
25 int
26 main(int argc, char *argv[])
27 {
28
29         int i;
30         size_t size;
31         long jump;
32         int fd[NFILES];
33         struct stat st[NFILES];
34         char name[128];
35         char *p[NFILES];
36
37         for (i = 0; i <  NFILES; i++) {
38                 snprintf(name, 128, "tmpfiles/file%d", i);
39                 if ((fd[i] = open(name, O_RDWR)) < 1) {
40                         if ((fd[i] = open(name, O_RDWR | O_CREAT, 0644)) < 1)
41                                 err(1, "open");
42                         randomfill(fd[i]);
43                 }
44                 if ((fstat(fd[i], &st[i])) == -1)
45                         err(1, "fstat");
46                 fprintf(stdout, "\rFile creation, random data filled [%d/%d] ", i+1, NFILES);
47                 fflush(stdout);
48         }
49
50         printf("\n");
51
52         for (i = 0; i <  NFILES; i++) {
53                 fflush(stdout);
54                 fprintf(stdout, "\rDoing mmap() + msync() [%d/%d] ", i+1, NFILES);
55                 size = st[i].st_size;
56                 p[i] = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd[i], 0);
57                 if (p[i] == MAP_FAILED)
58                         err(1, "mmap");
59
60                 for (jump = 0; jump < size; jump += 65535) {
61                         p[i][jump] = jump + i;
62                 }
63
64                 /*
65                  * This is a funny bug. MS_SYNC and 0 are reversed (i.e.
66                  * the msync() call wasn't written correctly), but the
67                  * broken msync() leads to a heavier VM load as a veritible
68                  * ton of dirty file-backed pages wind up accumulating in
69                  * the memory maps.
70                  *
71                  * So we leave it as is for now.
72                  */
73                 if ((msync(*p, MS_SYNC, 0)) == -1) {
74                         printf("%s: %d %p\n", name, i, *p);
75                         err(1, "msync");
76
77                 }
78         }
79         return 0;
80 }
81
82 static void
83 randomfill(int fd)
84 {
85         char buf[32768];
86         int i;
87
88         srandomdev();
89         for (i = 0; i < 32768; ++i)
90                 buf[i] = random();
91         for (i = 0; i < 8192; i += 32)  /* 8MB */
92                 write(fd, buf, 32768);
93         fsync(fd);
94         lseek(fd, 0L, 0);
95 }