blob: d8bf1c9e11187786ee2ffff925a14c7628d6a44d [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
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20/*
21 * FILE : mtest01.c
22 * DESCRIPTION : mallocs memory <chunksize> at a time until malloc fails.
23 * HISTORY:
24 * 04/10/2001 Paul Larson (plars@us.ibm.com)
25 * written
iyermanoj822caf52001-11-09 22:43:09 +000026 * 11/09/2001 Manoj Iyer (manjo@austin.ibm.com)
robbiew94a8bf12003-05-13 19:05:04 +000027 * Modified.
28 * - Removed compile warnings.
29 * - Added header file #include <unistd.h> definition for getopt()
30 * 05/13/2003 Robbie Williamson (robbiew@us.ibm.com)
31 * Modified.
32 * - Rewrote the test to be able to execute on large memory machines.
plars865695b2001-08-27 22:15:12 +000033 *
34 */
35
36#include <stdlib.h>
37#include <stdio.h>
iyermanoj822caf52001-11-09 22:43:09 +000038#include <unistd.h>
robbiew94a8bf12003-05-13 19:05:04 +000039#include <signal.h>
robbiewf5505642003-05-21 16:55:45 +000040#include <limits.h>
robbiew94a8bf12003-05-13 19:05:04 +000041#include <sys/sysinfo.h>
42#include <sys/types.h>
43#include <sys/wait.h>
plars865695b2001-08-27 22:15:12 +000044
45int main(int argc, char* argv[]) {
46 char* mem;
robbiew94a8bf12003-05-13 19:05:04 +000047 float percent;
robbiew15226cd2002-04-10 16:10:40 +000048 unsigned int maxpercent=0, dowrite=0, verbose=0, j, c;
robbiew94a8bf12003-05-13 19:05:04 +000049 unsigned long bytecount, alloc_bytes;
50 unsigned long long original_maxbytes,maxbytes=0;
51 unsigned long long pre_mem, post_mem;
plars865695b2001-08-27 22:15:12 +000052 extern char* optarg;
robbiewf3a83d52002-05-28 16:26:16 +000053 int chunksize = 1024*1024; /* one meg at a time by default */
plars865695b2001-08-27 22:15:12 +000054 struct sysinfo sstats;
robbiew94a8bf12003-05-13 19:05:04 +000055 int i;
56 pid_t pid,pid_list[1000];
57
58 for (i=0;i<1000;i++)
59 pid_list[i]=(pid_t)0;
plars865695b2001-08-27 22:15:12 +000060
61 while((c=getopt(argc, argv, "c:b:p:wvh")) != EOF) {
62 switch((char)c) {
63 case 'c':
64 chunksize = atoi(optarg);
65 break;
66 case 'b':
robbiew94a8bf12003-05-13 19:05:04 +000067 maxbytes = atoll(optarg);
plars865695b2001-08-27 22:15:12 +000068 break;
69 case 'p':
70 maxpercent = atoi(optarg);
71 break;
72 case 'w':
73 dowrite = 1;
74 break;
75 case 'v':
76 verbose = 1;
77 break;
78 case 'h':
79 default:
80 printf("Usage: %s [-c <bytes>] [-b <bytes>|-p <percent>] [-v]\n", argv[0]);
81 printf("\t-c <num>\tsize of chunk in bytes to malloc on each pass\n");
82 printf("\t-b <bytes>\tmaximum number of bytes to allocate before stopping\n");
83 printf("\t-p <bytes>\tpercent of total memory used at which the program stops\n");
84 printf("\t-w\t\twrite to the memory after allocating\n");
85 printf("\t-v\t\tverbose\n");
86 printf("\t-h\t\tdisplay usage\n");
87 exit(-1);
88 }
89 }
90
robbiew94a8bf12003-05-13 19:05:04 +000091 sysinfo(&sstats);
plars865695b2001-08-27 22:15:12 +000092 if(maxpercent) {
robbiew94a8bf12003-05-13 19:05:04 +000093 unsigned long long total_ram, total_free, D, C;
94 percent=(float)maxpercent/100.00;
95
96 total_ram=sstats.totalram;
97 total_ram=total_ram+sstats.totalswap;
98
99 total_free=sstats.freeram;
100 total_free=total_free+sstats.freeswap;
101
102 /* Total memory used needed to reach maxpercent */
103 D = percent*(sstats.mem_unit*total_ram);
104 printf("Total memory used needed to reach maxpercent = %llu kbytes\n",D/1024);
plars865695b2001-08-27 22:15:12 +0000105
106 /* Total memory already used */
robbiew94a8bf12003-05-13 19:05:04 +0000107 C = sstats.mem_unit*(total_ram-total_free);
108 printf("Total memory already used on system = %llu kbytes\n",C/1024);
109
110 /* Total Free Pre-Test RAM */
111 pre_mem = sstats.mem_unit*total_free;
plars865695b2001-08-27 22:15:12 +0000112
113 /* Are we already using more than maxpercent? */
114 if(C>D) {
115 printf("More memory than the maximum amount you specified is already being used\n");
116 exit(1);
117 }
robbiew94a8bf12003-05-13 19:05:04 +0000118 else
119 pre_mem = sstats.mem_unit*total_free;
120
plars865695b2001-08-27 22:15:12 +0000121
122 /* set maxbytes to the extra amount we want to allocate */
123 maxbytes = D-C;
robbiew94a8bf12003-05-13 19:05:04 +0000124 printf("Filling up %d%% of ram which is %llu kbytes\n",maxpercent,maxbytes/1024);
plars865695b2001-08-27 22:15:12 +0000125 }
robbiew94a8bf12003-05-13 19:05:04 +0000126 original_maxbytes=maxbytes;
127 i=0;
128 pid=fork();
129 pid_list[i]=pid;
robbiewf5505642003-05-21 16:55:45 +0000130
131#if __WORDSIZE==32
robbiew94a8bf12003-05-13 19:05:04 +0000132 while( (pid!=0) && (maxbytes > 1024*1024*1024) )
133 {
134 i++;
135 maxbytes=maxbytes-(1024*1024*1024);
136 pid=fork();
137 if (pid != 0)
138 pid_list[i]=pid;
139 }
140 if( maxbytes > 1024*1024*1024 )
141 alloc_bytes=1024*1024*1024;
142 else
143 alloc_bytes=(unsigned long)maxbytes;
robbiewf5505642003-05-21 16:55:45 +0000144#elif __WORDSIZE==64
145 while( (pid!=0) && (maxbytes > (unsigned long long)3*1024*1024*1024) )
146 {
147 i++;
robbiew94fb20d2003-05-22 22:06:44 +0000148 maxbytes=maxbytes-(unsigned long long)3*1024*1024*1024;
robbiewf5505642003-05-21 16:55:45 +0000149 pid=fork();
150 if (pid != 0)
151 pid_list[i]=pid;
152 }
153 if( maxbytes > (unsigned long long)3*1024*1024*1024 )
154 alloc_bytes=(unsigned long long)3*1024*1024*1024;
155 else
156 alloc_bytes=(unsigned long)maxbytes;
157#endif
robbiew94a8bf12003-05-13 19:05:04 +0000158
159 if ( pid == 0) /** CHILD **/
160 {
161 bytecount=chunksize;
162 while(1) {
163 if((mem = (char*)malloc(chunksize)) == NULL) {
164 printf("stopped at %lu bytes\n",bytecount);
165 exit(1);
166 }
167 if(dowrite)
168 for(j=0; j<chunksize; j++)
169 *(mem+j)='a';
170 if(verbose) printf("allocated %lu bytes chunksize is %d\n",bytecount,chunksize);
171 bytecount+=chunksize;
172 if(alloc_bytes && (bytecount >= alloc_bytes))
173 break;
plars865695b2001-08-27 22:15:12 +0000174 }
robbiew94a8bf12003-05-13 19:05:04 +0000175 if (dowrite)
176 printf("... %lu bytes allocated and used.\n",bytecount);
177 else
178 printf("... %lu bytes allocated only.\n",bytecount);
179 while(1)
180 sleep(1);
plars865695b2001-08-27 22:15:12 +0000181 }
robbiew94a8bf12003-05-13 19:05:04 +0000182 else /** PARENT **/
183 {
184 i=0;
185 sysinfo(&sstats);
186
187 if (dowrite)
188 {
189 /* Total Free Post-Test RAM */
190 post_mem = sstats.mem_unit*sstats.freeram;
191 post_mem = post_mem+(sstats.mem_unit*sstats.freeswap);
192
193 while ( (pre_mem - post_mem) < original_maxbytes )
194 {
195 sleep(1);
196 sysinfo(&sstats);
197 post_mem = sstats.mem_unit*sstats.freeram;
198 post_mem = post_mem+(sstats.mem_unit*sstats.freeswap);
199 }
200 }
201 sleep(10);
202 while (pid_list[i]!=0)
203 {
204 kill(pid_list[i],SIGTERM);
205 i++;
206 }
207 if (dowrite)
208 printf("PASS .. %llu kbytes allocated and used.\n",original_maxbytes/1024);
209 else
210 printf("PASS .. %llu kbytes allocated only.\n",original_maxbytes/1024);
211 }
plars865695b2001-08-27 22:15:12 +0000212 exit(0);
213}