plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 1 | /******************************************************************************/ |
| 2 | /* */ |
| 3 | /* Copyright (c) International Business Machines Corp., 2001 */ |
| 4 | /* */ |
| 5 | /* This program is free software; you can redistribute it and/or modify */ |
| 6 | /* it under the terms of the GNU General Public License as published by */ |
| 7 | /* the Free Software Foundation; either version 2 of the License, or */ |
| 8 | /* (at your option) any later version. */ |
| 9 | /* */ |
| 10 | /* This program is distributed in the hope that it will be useful, */ |
| 11 | /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ |
| 12 | /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ |
| 13 | /* the GNU General Public License for more details. */ |
| 14 | /* */ |
| 15 | /* You should have received a copy of the GNU General Public License */ |
| 16 | /* along with this program; if not, write to the Free Software */ |
Wanlong Gao | 4548c6c | 2012-10-19 18:03:36 +0800 | [diff] [blame] | 17 | /* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 18 | /* */ |
| 19 | /******************************************************************************/ |
| 20 | |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 21 | /******************************************************************************/ |
| 22 | /* */ |
| 23 | /* History: July - 02 - 2001 Created by Manoj Iyer, IBM Austin TX. */ |
| 24 | /* email:manjo@austin.ibm.com */ |
| 25 | /* */ |
| 26 | /* July - 07 - 2001 Modified - changed MAP_PRIVATE to MAP_SHARED */ |
| 27 | /* read defect 187 for details. */ |
| 28 | /* */ |
| 29 | /* July - 09 - 2001 Modified - added option to MAP_PRIVATE or */ |
| 30 | /* MAP_SHARED, -p, default is to MAP_SHARED. */ |
| 31 | /* */ |
| 32 | /* July - 09 - 2001 Modified - added option '-a' MAP_ANONYMOUS. */ |
| 33 | /* Default is to map a file. */ |
| 34 | /* */ |
| 35 | /* Aug - 01 - 2001 Modified - added option 'a' to getop list. */ |
iyermanoj | fec5115 | 2001-10-25 17:59:55 +0000 | [diff] [blame] | 36 | /* */ |
| 37 | /* Oct - 25 - 2001 Modified - changed scheme. Test will be run */ |
| 38 | /* once unless -x option is used. */ |
robbiew | 173b045 | 2003-04-16 19:46:42 +0000 | [diff] [blame] | 39 | /* */ |
| 40 | /* Apr - 16 - 2003 Modified - replaced tempnam() use with */ |
| 41 | /* mkstemp(). -Robbie Williamson */ |
| 42 | /* email:robbiew@us.ibm.com */ |
plars | 5260137 | 2003-05-12 22:04:16 +0000 | [diff] [blame] | 43 | /* */ |
| 44 | /* May - 12 - 2003 Modified - remove the huge files when */ |
| 45 | /* we are done with the test - Paul Larson */ |
| 46 | /* email:plars@linuxtestproject.org */ |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 47 | /* File: mmap2.c */ |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 48 | /* */ |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 49 | /* Description: Test the LINUX memory manager. The program is aimed at */ |
| 50 | /* stressing the memory manager by repeaded map/write/unmap of a */ |
| 51 | /* of a large gb size file. */ |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 52 | /* */ |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 53 | /* Create a file of the specified size in gb, map the file, */ |
| 54 | /* change the contents of the file and unmap it. This is repeated*/ |
| 55 | /* several times for the specified number of hours. */ |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 56 | /* */ |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 57 | /******************************************************************************/ |
| 58 | |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 59 | #include <stdio.h> |
| 60 | #include <sys/types.h> |
| 61 | #include <sys/stat.h> |
| 62 | #include <fcntl.h> |
| 63 | #include <unistd.h> |
| 64 | #include <errno.h> |
| 65 | #include <sys/mman.h> |
| 66 | #include <sched.h> |
| 67 | #include <stdlib.h> |
| 68 | #include <signal.h> |
| 69 | #include <sys/time.h> |
| 70 | #include <sys/wait.h> |
| 71 | #include <signal.h> |
robbiew | 88e7b18 | 2003-03-13 19:00:13 +0000 | [diff] [blame] | 72 | #include <string.h> |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 73 | #include <getopt.h> |
robbiew | 173b045 | 2003-04-16 19:46:42 +0000 | [diff] [blame] | 74 | #include "test.h" |
robbiew | 173b045 | 2003-04-16 19:46:42 +0000 | [diff] [blame] | 75 | |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 76 | #define GB 1000000000 |
| 77 | #ifndef TRUE |
| 78 | #define TRUE 1 |
| 79 | #endif |
| 80 | #ifndef FALSE |
| 81 | #define FALSE 0 |
| 82 | #endif |
| 83 | |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 84 | static int mkfile(int size) |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 85 | { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 86 | int fd; |
| 87 | int index = 0; |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 88 | char buff[4096]; |
| 89 | char template[PATH_MAX]; |
robbiew | 173b045 | 2003-04-16 19:46:42 +0000 | [diff] [blame] | 90 | |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 91 | memset(buff, 'a', 4096); |
| 92 | snprintf(template, PATH_MAX, "ashfileXXXXXX"); |
| 93 | fd = mkstemp(template); |
| 94 | if (fd == -1) { |
| 95 | perror("mkfile(): mkstemp()"); |
| 96 | return -1; |
| 97 | } else { |
| 98 | unlink(template); |
| 99 | fprintf(stdout, "creating tmp file and writing 'a' to it "); |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 100 | } |
Garrett Cooper | 2c28215 | 2010-12-16 00:55:50 -0800 | [diff] [blame] | 101 | |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 102 | while (index < (size * GB)) { |
| 103 | index += 4096; |
| 104 | if (write(fd, buff, 4096) == -1) { |
| 105 | perror("mkfile(): write()"); |
| 106 | return -1; |
| 107 | } |
| 108 | } |
| 109 | fprintf(stdout, "created file of size %d\n" |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 110 | "content of the file is 'a'\n", index); |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 111 | |
| 112 | if (fsync(fd) == -1) { |
| 113 | perror("mkfile(): fsync()"); |
| 114 | return -1; |
| 115 | } |
| 116 | return fd; |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 117 | } |
| 118 | |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 119 | static void sig_handler(int signal) |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 120 | { |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 121 | if (signal != SIGALRM) { |
| 122 | fprintf(stderr, "sig_handlder(): unexpected signal caught" |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 123 | "[%d]\n", signal); |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 124 | exit(-1); |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 125 | } else |
| 126 | fprintf(stdout, "Test ended, success\n"); |
| 127 | exit(0); |
| 128 | } |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 129 | |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 130 | static void usage(char *progname) |
| 131 | { |
| 132 | fprintf(stderr, |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 133 | "Usage: %s -h -s -x\n" |
| 134 | "\t -a set map_flags to MAP_ANONYMOUS\n" |
| 135 | "\t -h help, usage message.\n" |
| 136 | "\t -p set map_flag to MAP_PRIVATE.\tdefault:" |
| 137 | "MAP_SHARED\n" |
| 138 | "\t -s size of the file/memory to be mmaped.\tdefault:" |
| 139 | "1GB\n" |
| 140 | "\t -x time for which test is to be run.\tdefault:" |
| 141 | "24 Hrs\n", progname); |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 142 | exit(-1); |
| 143 | } |
| 144 | |
| 145 | int main(int argc, char **argv) |
| 146 | { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 147 | int fd; |
| 148 | int fsize = 1; |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 149 | float exec_time = 24; |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 150 | int c; |
| 151 | int sig_ndx; |
| 152 | int map_flags = MAP_SHARED; |
| 153 | int map_anon = FALSE; |
| 154 | int run_once = TRUE; |
| 155 | char *memptr; |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 156 | struct sigaction sigptr; |
| 157 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 158 | static struct signal_info { |
| 159 | int signum; |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 160 | char *signame; |
| 161 | } sig_info[] = { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 162 | { |
| 163 | SIGHUP, "SIGHUP"}, { |
| 164 | SIGINT, "SIGINT"}, { |
| 165 | SIGQUIT, "SIGQUIT"}, { |
| 166 | SIGABRT, "SIGABRT"}, { |
| 167 | SIGBUS, "SIGBUS"}, { |
| 168 | SIGSEGV, "SIGSEGV"}, { |
| 169 | SIGALRM, "SIGALRM"}, { |
| 170 | SIGUSR1, "SIGUSR1"}, { |
| 171 | SIGUSR2, "SIGUSR2"}, { |
| 172 | -1, "ENDSIG"} |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 173 | }; |
| 174 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 175 | while ((c = getopt(argc, argv, "ahps:x:")) != -1) { |
| 176 | switch (c) { |
| 177 | case 'a': |
| 178 | map_anon = TRUE; |
| 179 | break; |
| 180 | case 'h': |
| 181 | usage(argv[0]); |
| 182 | exit(-1); |
| 183 | break; |
| 184 | case 'p': |
| 185 | map_flags = MAP_PRIVATE; |
| 186 | break; |
| 187 | case 's': |
| 188 | fsize = atoi(optarg); |
| 189 | if (fsize == 0) |
| 190 | fprintf(stderr, "Using default " |
| 191 | "fsize %d GB\n", fsize = 1); |
| 192 | break; |
| 193 | case 'x': |
| 194 | exec_time = atof(optarg); |
| 195 | if (exec_time == 0) |
| 196 | fprintf(stderr, "Using default exec " |
| 197 | "time %f hrs", exec_time = (float)24); |
| 198 | run_once = FALSE; |
| 199 | break; |
| 200 | default: |
| 201 | usage(argv[0]); |
| 202 | break; |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 203 | } |
| 204 | } |
| 205 | |
| 206 | fprintf(stdout, "MM Stress test, map/write/unmap large file\n" |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 207 | "\tTest scheduled to run for: %f\n" |
| 208 | "\tSize of temp file in GB: %d\n", exec_time, fsize); |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 209 | |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 210 | alarm(exec_time * 3600.00); |
Garrett Cooper | 2c28215 | 2010-12-16 00:55:50 -0800 | [diff] [blame] | 211 | |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 212 | sigptr.sa_handler = sig_handler; |
| 213 | sigfillset(&sigptr.sa_mask); |
| 214 | sigptr.sa_flags = 0; |
| 215 | for (sig_ndx = 0; sig_info[sig_ndx].signum != -1; sig_ndx++) { |
| 216 | sigaddset(&sigptr.sa_mask, sig_info[sig_ndx].signum); |
| 217 | if (sigaction(sig_info[sig_ndx].signum, &sigptr, |
Cyril Hrubis | cf0d626 | 2014-09-23 14:03:31 +0200 | [diff] [blame] | 218 | NULL) == -1) { |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 219 | perror("man(): sigaction()"); |
| 220 | fprintf(stderr, "could not set handler for SIGALRM," |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 221 | "errno = %d\n", errno); |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 222 | exit(-1); |
| 223 | } |
| 224 | } |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 225 | |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 226 | do { |
| 227 | if (!map_anon) { |
| 228 | fd = mkfile(fsize); |
| 229 | if (fd == -1) { |
| 230 | fprintf(stderr, "main(): mkfile(): Failed " |
| 231 | "to create temp file.\n"); |
| 232 | exit(-1); |
| 233 | } |
| 234 | } else { |
| 235 | fd = -1; |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 236 | map_flags = map_flags | MAP_ANONYMOUS; |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 237 | } |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 238 | memptr = mmap(0, (fsize * GB), PROT_READ | PROT_WRITE, |
| 239 | map_flags, fd, 0); |
| 240 | if (memptr == MAP_FAILED) { |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 241 | perror("main(): mmap()"); |
| 242 | exit(-1); |
| 243 | } else |
| 244 | fprintf(stdout, "file mapped at %p\n" |
| 245 | "changing file content to 'A'\n", memptr); |
Garrett Cooper | 2c28215 | 2010-12-16 00:55:50 -0800 | [diff] [blame] | 246 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 247 | memset(memptr, 'A', ((fsize * GB) / sizeof(char))); |
Garrett Cooper | 2c28215 | 2010-12-16 00:55:50 -0800 | [diff] [blame] | 248 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 249 | if (msync(memptr, ((fsize * GB) / sizeof(char)), |
| 250 | MS_SYNC | MS_INVALIDATE) == -1) { |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 251 | perror("main(): msync()"); |
| 252 | exit(-1); |
| 253 | } |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 254 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 255 | if (munmap(memptr, (fsize * GB) / sizeof(char)) == -1) { |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 256 | perror("main(): munmap()"); |
| 257 | exit(-1); |
| 258 | } else |
| 259 | fprintf(stdout, "unmapped file at %p\n", memptr); |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 260 | |
Shang Yanfeng | 6d6af4a | 2012-02-02 13:52:43 +0800 | [diff] [blame] | 261 | close(fd); |
| 262 | sync(); |
| 263 | } while (TRUE && !run_once); |
| 264 | exit(0); |
Cyril Hrubis | fea169d | 2011-11-09 16:28:30 +0100 | [diff] [blame] | 265 | } |