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