| Commit | Line | Data |
|---|---|---|
| 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 | |
| 23 | static void randomfill(int fd); | |
| 1923035e AHJ |
24 | static int mmap01(void *); |
| 25 | static int mmap02(void *); | |
| 26 | static int build_files(void); | |
| d921454f | 27 | |
| 1923035e AHJ |
28 | int opt_verbose; |
| 29 | int opt_testno; | |
| 30 | int opt_nofiles; | |
| 31 | int opt_mbfile; | |
| 32 | int opt_count; | |
| 33 | int fliparg; | |
| 34 | ||
| 35 | int *fd; | |
| 36 | struct stat *st; | |
| 37 | char **pp; | |
| 38 | ||
| 39 | static 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 | ||
| 48 | static int | |
| 49 | mmap01(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 | ||
| 93 | static int | |
| 94 | mmap02(void *arg) | |
| 95 | { | |
| 96 | fliparg = 1; | |
| 97 | mmap01(&fliparg); | |
| 98 | ||
| 99 | return 0; | |
| 100 | } | |
| 101 | ||
| 102 | static void | |
| 103 | usage(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 | ||
| 116 | int | |
| 117 | main(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 |
170 | static int |
| 171 | build_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 |
199 | static void |
| 200 | randomfill(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 | } |