blob: ad81dbe571d396203d45a564048431e5422b2463 [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/******************************************************************************/
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 Gao4548c6c2012-10-19 18:03:36 +080017/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
plars865695b2001-08-27 22:15:12 +000018/* */
19/******************************************************************************/
20
plars865695b2001-08-27 22:15:12 +000021/******************************************************************************/
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. */
iyermanojfec51152001-10-25 17:59:55 +000036/* */
37/* Oct - 25 - 2001 Modified - changed scheme. Test will be run */
38/* once unless -x option is used. */
robbiew173b0452003-04-16 19:46:42 +000039/* */
40/* Apr - 16 - 2003 Modified - replaced tempnam() use with */
41/* mkstemp(). -Robbie Williamson */
42/* email:robbiew@us.ibm.com */
plars52601372003-05-12 22:04:16 +000043/* */
44/* May - 12 - 2003 Modified - remove the huge files when */
45/* we are done with the test - Paul Larson */
46/* email:plars@linuxtestproject.org */
plars865695b2001-08-27 22:15:12 +000047/* File: mmap2.c */
Shang Yanfeng6d6af4a2012-02-02 13:52:43 +080048/* */
plars865695b2001-08-27 22:15:12 +000049/* 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 Yanfeng6d6af4a2012-02-02 13:52:43 +080052/* */
plars865695b2001-08-27 22:15:12 +000053/* 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 Yanfeng6d6af4a2012-02-02 13:52:43 +080056/* */
plars865695b2001-08-27 22:15:12 +000057/******************************************************************************/
58
plars865695b2001-08-27 22:15:12 +000059#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>
robbiew88e7b182003-03-13 19:00:13 +000072#include <string.h>
Shang Yanfeng6d6af4a2012-02-02 13:52:43 +080073#include <getopt.h>
robbiew173b0452003-04-16 19:46:42 +000074#include "test.h"
robbiew173b0452003-04-16 19:46:42 +000075
plars865695b2001-08-27 22:15:12 +000076#define GB 1000000000
77#ifndef TRUE
78#define TRUE 1
79#endif
80#ifndef FALSE
81#define FALSE 0
82#endif
83
Shang Yanfeng6d6af4a2012-02-02 13:52:43 +080084static int mkfile(int size)
plars865695b2001-08-27 22:15:12 +000085{
Wanlong Gao354ebb42012-12-07 10:10:04 +080086 int fd;
87 int index = 0;
Shang Yanfeng6d6af4a2012-02-02 13:52:43 +080088 char buff[4096];
89 char template[PATH_MAX];
robbiew173b0452003-04-16 19:46:42 +000090
Shang Yanfeng6d6af4a2012-02-02 13:52:43 +080091 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 ");
plars865695b2001-08-27 22:15:12 +0000100 }
Garrett Cooper2c282152010-12-16 00:55:50 -0800101
Shang Yanfeng6d6af4a2012-02-02 13:52:43 +0800102 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 Gao354ebb42012-12-07 10:10:04 +0800110 "content of the file is 'a'\n", index);
Shang Yanfeng6d6af4a2012-02-02 13:52:43 +0800111
112 if (fsync(fd) == -1) {
113 perror("mkfile(): fsync()");
114 return -1;
115 }
116 return fd;
plars865695b2001-08-27 22:15:12 +0000117}
118
Shang Yanfeng6d6af4a2012-02-02 13:52:43 +0800119static void sig_handler(int signal)
plars865695b2001-08-27 22:15:12 +0000120{
Shang Yanfeng6d6af4a2012-02-02 13:52:43 +0800121 if (signal != SIGALRM) {
122 fprintf(stderr, "sig_handlder(): unexpected signal caught"
Wanlong Gao354ebb42012-12-07 10:10:04 +0800123 "[%d]\n", signal);
plars865695b2001-08-27 22:15:12 +0000124 exit(-1);
Shang Yanfeng6d6af4a2012-02-02 13:52:43 +0800125 } else
126 fprintf(stdout, "Test ended, success\n");
127 exit(0);
128}
plars865695b2001-08-27 22:15:12 +0000129
Shang Yanfeng6d6af4a2012-02-02 13:52:43 +0800130static void usage(char *progname)
131{
132 fprintf(stderr,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800133 "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 Yanfeng6d6af4a2012-02-02 13:52:43 +0800142 exit(-1);
143}
144
145int main(int argc, char **argv)
146{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800147 int fd;
148 int fsize = 1;
Shang Yanfeng6d6af4a2012-02-02 13:52:43 +0800149 float exec_time = 24;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800150 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 Yanfeng6d6af4a2012-02-02 13:52:43 +0800156 struct sigaction sigptr;
157
Wanlong Gao354ebb42012-12-07 10:10:04 +0800158 static struct signal_info {
159 int signum;
Shang Yanfeng6d6af4a2012-02-02 13:52:43 +0800160 char *signame;
161 } sig_info[] = {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800162 {
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 Yanfeng6d6af4a2012-02-02 13:52:43 +0800173 };
174
Wanlong Gao354ebb42012-12-07 10:10:04 +0800175 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 Yanfeng6d6af4a2012-02-02 13:52:43 +0800203 }
204 }
205
206 fprintf(stdout, "MM Stress test, map/write/unmap large file\n"
Wanlong Gao354ebb42012-12-07 10:10:04 +0800207 "\tTest scheduled to run for: %f\n"
208 "\tSize of temp file in GB: %d\n", exec_time, fsize);
plars865695b2001-08-27 22:15:12 +0000209
Shang Yanfeng6d6af4a2012-02-02 13:52:43 +0800210 alarm(exec_time * 3600.00);
Garrett Cooper2c282152010-12-16 00:55:50 -0800211
Shang Yanfeng6d6af4a2012-02-02 13:52:43 +0800212 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 Hrubiscf0d6262014-09-23 14:03:31 +0200218 NULL) == -1) {
Shang Yanfeng6d6af4a2012-02-02 13:52:43 +0800219 perror("man(): sigaction()");
220 fprintf(stderr, "could not set handler for SIGALRM,"
Wanlong Gao354ebb42012-12-07 10:10:04 +0800221 "errno = %d\n", errno);
Shang Yanfeng6d6af4a2012-02-02 13:52:43 +0800222 exit(-1);
223 }
224 }
plars865695b2001-08-27 22:15:12 +0000225
Shang Yanfeng6d6af4a2012-02-02 13:52:43 +0800226 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 Gao354ebb42012-12-07 10:10:04 +0800236 map_flags = map_flags | MAP_ANONYMOUS;
Shang Yanfeng6d6af4a2012-02-02 13:52:43 +0800237 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800238 memptr = mmap(0, (fsize * GB), PROT_READ | PROT_WRITE,
239 map_flags, fd, 0);
240 if (memptr == MAP_FAILED) {
Shang Yanfeng6d6af4a2012-02-02 13:52:43 +0800241 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 Cooper2c282152010-12-16 00:55:50 -0800246
Wanlong Gao354ebb42012-12-07 10:10:04 +0800247 memset(memptr, 'A', ((fsize * GB) / sizeof(char)));
Garrett Cooper2c282152010-12-16 00:55:50 -0800248
Wanlong Gao354ebb42012-12-07 10:10:04 +0800249 if (msync(memptr, ((fsize * GB) / sizeof(char)),
250 MS_SYNC | MS_INVALIDATE) == -1) {
Shang Yanfeng6d6af4a2012-02-02 13:52:43 +0800251 perror("main(): msync()");
252 exit(-1);
253 }
plars865695b2001-08-27 22:15:12 +0000254
Wanlong Gao354ebb42012-12-07 10:10:04 +0800255 if (munmap(memptr, (fsize * GB) / sizeof(char)) == -1) {
Shang Yanfeng6d6af4a2012-02-02 13:52:43 +0800256 perror("main(): munmap()");
257 exit(-1);
258 } else
259 fprintf(stdout, "unmapped file at %p\n", memptr);
plars865695b2001-08-27 22:15:12 +0000260
Shang Yanfeng6d6af4a2012-02-02 13:52:43 +0800261 close(fd);
262 sync();
263 } while (TRUE && !run_once);
264 exit(0);
Cyril Hrubisfea169d2011-11-09 16:28:30 +0100265}