• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  *   Copyright (c) International Business Machines  Corp., 2002
4  *   Copyright (c) 2012 Cyril Hrubis <chrubis@suse.cz>
5  *
6  *   This program is free software;  you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14  *   the GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program;  if not, write to the Free Software
18  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /* IBM Corporation */
22 /* 06/30/2001	Port to Linux	nsharoff@us.ibm.com */
23 /* 10/30/2002	Port to LTP	dbarrera@us.ibm.com */
24 
25 /*======================================================================
26 /	=================== TESTPLAN SEGMENT ===================
27 >KEYS:	< calloc, malloc, free, realloc, valloc
28 >WHAT:	< check that memory can be allocated and freed. check for zeroed
29    	< memory.
30 >HOW:	< Allocate a big chunk of memory, verify it is available (zeroed
31 	< in the case of calloc).
32 	< Write into it and verify, free memory and verify free was
33 	< successful.
34 	< In the case of valloc, allocate memory and free it (do this for
35 	< several iterations). Check if valloc returns unaligned pointers.
36 	< If valloc causes a SIGSEGV, that means a failure has occured.
37 >BUGS:	<
38 ======================================================================*/
39 
40 #include <stdio.h>
41 #include <signal.h>
42 #include <stdlib.h>
43 #include "test.h"
44 #include <unistd.h>
45 #include <errno.h>
46 #include <time.h>
47 #include <string.h>
48 #include <sys/types.h>
49 #include <sys/user.h>
50 
51 #define MEMSIZE	8192 * 8192
52 
53 void on_mem_fault(int sig);
54 
55 char *TCID = "mem02";
56 int TST_TOTAL = 1;
57 
usage(char * progname)58 static void usage(char *progname)
59 {
60 	fprintf(stderr, "usage: %s -m memsize\n", progname);
61 	fprintf(stderr, "\t-m specify the size of memory to allocate, in MB\n");
62 	exit(1);
63 }
64 
get_pagesize_order(void)65 static int get_pagesize_order(void)
66 {
67 	int i, pagesize, size = 0;
68 	pagesize = sysconf(_SC_PAGESIZE);
69 	for (i = 0; size != pagesize; i++)
70 		size = 1 << i;
71 	return (i - 1);
72 }
73 
main(int argc,char ** argv)74 int main(int argc, char **argv)
75 {
76 	int i;
77 	char *pm1, *pm2, *pm3, *pm4;
78 	void *memptr;
79 	long laddr;
80 	int iteration_count;
81 	int size;		/* Size to memory to be valloced */
82 	int pagesize_order = get_pagesize_order();
83 	int memsize = MEMSIZE;	/* Size of memory to allocate */
84 	extern char *optarg;	/* getopt() function global variables */
85 	extern int optopt;	/* stores bad option passed to the program */
86 	int ch;
87 
88 	optarg = NULL;
89 	opterr = 0;
90 
91 	while ((ch = getopt(argc, argv, "m:")) != -1) {
92 		switch (ch) {
93 		case 'm':
94 			if (optarg)
95 				memsize = atoi(optarg) * 1024 * 1024;
96 			else
97 				fprintf(stderr, "%s: option -%c requires "
98 					"an argument\n", argv[0], optopt);
99 			break;
100 		default:
101 			usage(argv[0]);
102 			exit(1);
103 		}
104 	}
105 
106 	/* check out calloc/free */
107 	if ((pm2 = pm1 = calloc(memsize, 1)) == NULL) {
108 
109 		tst_brkm(TFAIL, NULL, "calloc - alloc of %dMB failed",
110 			 memsize / 1024 / 1024);
111 	}
112 
113 	for (i = 0; i < memsize; i++)
114 		if (*pm2++ != 0) {
115 			tst_brkm(TFAIL, NULL,
116 				 "calloc returned non zero memory");
117 		}
118 
119 	pm2 = pm1;
120 	for (i = 0; i < memsize; i++)
121 		*pm2++ = 'X';
122 	pm2 = pm1;
123 	for (i = 0; i < memsize; i++)
124 		if (*pm2++ != 'X') {
125 			tst_brkm(TFAIL, NULL,
126 				 "could not write/verify memory ");
127 		}
128 
129 	free(pm1);
130 
131 	tst_resm(TPASS, "calloc - calloc of %uMB of memory succeeded",
132 		 memsize / 1024 / 1024);
133 
134 /*--------------------------------------------------------------------*/
135 
136 	/* check out malloc/free */
137 	if ((pm2 = pm1 = malloc(memsize)) == NULL) {
138 		tst_brkm(TFAIL, NULL, "malloc did not alloc memory ");
139 	}
140 
141 	for (i = 0; i < memsize; i++)
142 		*pm2++ = 'X';
143 	pm2 = pm1;
144 	for (i = 0; i < memsize; i++)
145 		if (*pm2++ != 'X') {
146 			tst_brkm(TFAIL, NULL,
147 				 "could not write/verify memory ");
148 		}
149 
150 	free(pm1);
151 
152 	tst_resm(TPASS, "malloc - malloc of %uMB of memory succeeded",
153 		 memsize / 1024 / 1024);
154 
155 /*--------------------------------------------------------------------*/
156 
157 	/* check out realloc */
158 
159 	pm4 = pm3 = malloc(10);
160 	for (i = 0; i < 10; i++)
161 		*pm4++ = 'X';
162 
163 	/* realloc with reduced size */
164 	pm4 = realloc(pm3, 5);
165 	pm3 = pm4;
166 	/* verify contents did not change */
167 	for (i = 0; i < 5; i++) {
168 		if (*pm4++ != 'X') {
169 			tst_brkm(TFAIL, NULL,
170 				 "realloc changed memory contents");
171 		}
172 	}
173 
174 	tst_resm(TPASS, "realloc - realloc of 5 bytes succeeded");
175 
176 	/* realloc with increased size after fragmenting memory */
177 	pm4 = realloc(pm3, 15);
178 	pm3 = pm4;
179 	/* verify contents did not change */
180 	for (i = 0; i < 5; i++) {
181 		if (*pm3++ != 'X') {
182 			tst_brkm(TFAIL, NULL,
183 				 "realloc changed memory contents");
184 		}
185 	}
186 
187 	tst_resm(TPASS, "realloc - realloc of 15 bytes succeeded");
188 	free(pm4);
189 
190 /*--------------------------------------------------------------------*/
191 	/*
192 	 * Check out for valloc failures
193 	 */
194 
195 	/*
196 	 * Setup to catch the memory fault, otherwise the core might
197 	 * be dumped on failures.
198 	 */
199 	if ((signal(SIGSEGV, on_mem_fault)) == SIG_ERR) {
200 		tst_brkm(TFAIL, NULL,
201 			 "Could not get signal handler for SIGSEGV");
202 	}
203 
204 	srand(1);		/* Ensure Determinism         */
205 
206 	for (iteration_count = 15000; iteration_count > 0; iteration_count--) {
207 		/*
208 		 * size is a fraction of 100000 and is determined by rand().
209 		 */
210 		size = (int)((rand() / (float)RAND_MAX) * 100000) + 1;
211 		memptr = valloc(size);
212 
213 		/*
214 		 * Check to see if valloc returns unaligned data.
215 		 * This can be done by copying the memory address into
216 		 * a variable and the by diving and multipying the address
217 		 * by the pagesize order and checking.
218 		 */
219 		laddr = (long)memptr;
220 		if (((laddr >> pagesize_order) << pagesize_order) != laddr) {
221 			tst_brkm(TFAIL, NULL,
222 				 "Valloc returned unaligned data");
223 		}
224 
225 		free(memptr);
226 	}
227 	tst_resm(TPASS, "valloc - valloc of rand() size of memory succeeded "
228 		 "for 15000 iteration");
229 
230 	tst_exit();
231 }
232 
233 /*
234  * void
235  * on_mem_fault(int sig)
236  *
237  *	on_mem_fault() is a signal handler used by the valloc test-case
238  *	(block 3). This function will catch the signal, indicate a failure,
239  *	write to the log file (a failure message) and exit the test.
240  */
on_mem_fault(int sig)241 void on_mem_fault(int sig)
242 {
243 	tst_brkm(TFAIL, NULL, "\tTest failed on receipt of a SIGSEGV signal");
244 }
245