]> git.ipfire.org Git - thirdparty/squid.git/blob - test-suite/membanger.c
SourceFormat Enforcement
[thirdparty/squid.git] / test-suite / membanger.c
1 /*
2 * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9 #include "squid.h"
10 #include "hash.h"
11
12 #if HAVE_UNISTD_H
13 #include <unistd.h>
14 #endif
15 #if HAVE_CTYPE_H
16 #include <ctype.h>
17 #endif
18 #if HAVE_STRINGS_H
19 #include <strings.h>
20 #endif
21
22 static hash_table *mem_table = NULL;
23 static hash_link *mem_entry;
24 struct rusage myusage;
25
26 #ifdef WITH_LIB
27 #include "Mem.h"
28 #include <assert.h>
29 extern void sizeToPoolInit();
30 extern MemPool *sizeToPool(size_t size);
31 #endif
32 extern char *malloc_options;
33 void my_free(char *, int, void *);
34
35 FILE *fp;
36 char *fn;
37 int initsiz;
38 int maxsiz;
39 int minchunk;
40 HASHCMP ptrcmp;
41 char mbuf[256];
42 char abuf[32];
43 char *p;
44
45 int size;
46 void *addr;
47 int amt;
48
49 int i;
50 int a;
51 int run_stats = 0;
52 void *my_xmalloc(size_t);
53 void *my_xcalloc(int, size_t);
54 int my_xfree(void *);
55
56 #define xmalloc my_xmalloc
57 #define xcalloc my_xcalloc
58 #define xfree my_xfree
59
60 int *size2id_array[2];
61 int size2id_len = 0;
62 int size2id_alloc = 0;
63
64 typedef struct {
65 char orig_ptr[32];
66 void *my_ptr;
67 #ifdef WITH_LIB
68 MemPool *pool;
69 #endif
70 int size;
71 } memitem;
72
73 struct {
74 int mallocs, frees, callocs, reallocs;
75 } mstat;
76
77 memitem *mi;
78 void size2id(size_t, memitem *);
79 void badformat();
80 void init_stats(), print_stats();
81 void my_hash_insert(hash_table * h, const char *k, memitem * item);
82 static void *xmemAlloc(memitem * item);
83 static void xmemFree(memitem * item);
84
85 int
86 ptrcmp(const void *a, const void *b)
87 {
88 return (strcmp(a, b));
89 }
90
91 main(int argc, char **argv)
92 {
93 char c;
94 extern char *optarg;
95 malloc_options = "A";
96 a = 0;
97 while ((c = getopt(argc, argv, "f:i:M:l:m:r:N")) != -1) {
98 switch (c) {
99 case 'N':
100 mem_pools_on = 0;
101 break;
102 case 'r':
103 run_stats = atoi(optarg);
104 break;
105 case 'f':
106 fn = xstrdup(optarg);
107 fp = fopen(fn, "r");
108 break;
109 case 'i':
110 initsiz = atoi(optarg);
111 break;
112 case 'l':
113 mem_max_size = atoi(optarg) * 1024 * 1024;
114 break;
115 case 'M':
116 maxsiz = atoi(optarg);
117 break;
118 case 'm':
119 minchunk = atoi(optarg);
120 break;
121 default:
122 fprintf(stderr,
123 "Usage: %s -f file -M maxsiz -i initsiz -m minchunk", argv[0]);
124 exit(1);
125 }
126
127 }
128 if (!fp) {
129 fprintf(stderr,
130 "%s pummels %s\n%s . o O ( You't supply a valid tracefile.)\n",
131 argv[0], getenv("USER"), argv[0]);
132 exit(1);
133 }
134 #ifdef WITH_LIB
135 sizeToPoolInit();
136 #endif
137 mem_table = hash_create(ptrcmp, 229, hash4); /* small hash table */
138 init_stats();
139 while (fgets(mbuf, 256, fp) != NULL) {
140 if (run_stats > 0 && (++a) % run_stats == 0)
141 print_stats();
142 p = NULL;
143 switch (mbuf[0]) {
144 case 'm': /* malloc */
145 p = strtok(&mbuf[2], ":");
146 if (!p)
147 badformat();
148 size = atoi(p);
149 p = strtok(NULL, "\n");
150 if (!p)
151 badformat();
152 mi = malloc(sizeof(memitem));
153 strcpy(mi->orig_ptr, p);
154 mi->size = size;
155 size2id(size, mi);
156 mi->my_ptr = xmemAlloc(mi); /* (void *)xmalloc(size); */
157 assert(mi->my_ptr);
158 my_hash_insert(mem_table, mi->orig_ptr, mi);
159 mstat.mallocs++;
160 break;
161 case 'c': /* calloc */
162 p = strtok(&mbuf[2], ":");
163 if (!p)
164 badformat();
165 amt = atoi(p);
166 p = strtok(NULL, ":");
167 if (!p)
168 badformat();
169 size = atoi(p);
170 p = strtok(NULL, "\n");
171 if (!p)
172 badformat();
173 mi = malloc(sizeof(memitem));
174 strcpy(mi->orig_ptr, p);
175 size2id(size, mi);
176 mi->size = amt * size;
177 mi->my_ptr = xmemAlloc(mi); /*(void *)xmalloc(amt*size); */
178 assert(mi->my_ptr);
179 my_hash_insert(mem_table, mi->orig_ptr, mi);
180 mstat.callocs++;
181 break;
182 case 'r':
183 p = strtok(&mbuf[2], ":");
184 if (!p)
185 badformat();
186 strcpy(abuf, p);
187 p = strtok(NULL, ":");
188 if (!p)
189 badformat();
190 mem_entry = hash_lookup(mem_table, p);
191 if (mem_entry == NULL) {
192 fprintf(stderr, "invalid realloc (%s)!\n", p);
193 break;
194 }
195 mi = (memitem *) (mem_entry->item);
196 assert(mi->pool);
197 assert(mi->my_ptr);
198 xmemFree(mi); /* xfree(mi->my_ptr); */
199 size2id(atoi(p), mi); /* we don't need it here I guess? */
200 strcpy(mi->orig_ptr, abuf);
201 p = strtok(NULL, "\n");
202 if (!p)
203 badformat();
204 mi->my_ptr = xmemAlloc(mi); /* (char *)xmalloc(atoi(p)); */
205 assert(mi->my_ptr);
206 mstat.reallocs++;
207 break;
208 case 'f':
209 p = strtok(&mbuf[2], "\n");
210 mem_entry = hash_lookup(mem_table, p);
211 if (mem_entry == NULL) {
212 if (p[0] != '0')
213 fprintf(stderr, "invalid free (%s) at line %d!\n", p, a);
214 break;
215 }
216 mi = (memitem *) (mem_entry->item);
217 assert(mi->pool);
218 assert(mi->my_ptr);
219 xmemFree(mi); /* xfree(mi->my_ptr); */
220 hash_unlink(mem_table, mem_entry, 1);
221 free(mi);
222 mstat.frees++;
223 break;
224 default:
225 fprintf(stderr, "%s pummels %s.bad.format\n", argv[0], fn);
226 exit(1);
227 }
228
229 }
230 fclose(fp);
231 print_stats();
232 }
233
234 void *
235 my_xmalloc(size_t a)
236 {
237 return NULL;
238 }
239
240 void *
241 my_xcalloc(int a, size_t b)
242 {
243 return NULL;
244 }
245
246 int
247 my_xfree(void *p)
248 {
249 return 0;
250 }
251 void
252 init_stats()
253 {
254
255 }
256
257 void
258 print_stats()
259 {
260 #ifdef WITH_LIB
261 memReport(stdout);
262 #endif
263 getrusage(RUSAGE_SELF, &myusage);
264 printf("m/c/f/r=%d/%d/%d/%d\n", mstat.mallocs, mstat.callocs,
265 mstat.frees, mstat.reallocs);
266 #if 0
267 printf("types : %d\n", size2id_len);
268 #endif
269 printf("user time used : %d.%d\n", (int) myusage.ru_utime.tv_sec,
270 (int) myusage.ru_utime.tv_usec);
271 printf("system time used : %d.%d\n", (int) myusage.ru_stime.tv_sec,
272 (int) myusage.ru_stime.tv_usec);
273 printf("max resident set size : %d\n", (int) myusage.ru_maxrss);
274 printf("page faults : %d\n", (int) myusage.ru_majflt);
275 }
276
277 void
278 size2id(size_t sz, memitem * mi)
279 {
280 #ifdef WITH_LIB
281 mi->pool = sizeToPool(sz);
282 assert(mi->pool);
283 #endif
284 return;
285 }
286
287 void
288 badformat()
289 {
290 fprintf(stderr, "pummel.bad.format\n");
291 exit(1);
292 }
293
294 /* unused code, saved for parts */
295 const char *
296 make_nam(int id, int size)
297 {
298 const char *buf = malloc(30); /* argh */
299 snprintf((char *)buf, sizeof(buf)-1, "pl:%d/%d", id, size);
300 return buf;
301 }
302
303 void
304 my_hash_insert(hash_table * h, const char *k, memitem * item)
305 {
306 memitem *l;
307 assert(item->pool);
308 assert(item->my_ptr);
309 hash_insert(h, k, item);
310 }
311
312 static void *
313 xmemAlloc(memitem * item)
314 {
315 extern MemPool *StringPool;
316 assert(item && item->pool);
317 if (StringPool == item->pool)
318 return memStringAlloc(item->pool, item->size);
319 else
320 return memAlloc(item->pool);
321 }
322
323 static void
324 xmemFree(memitem * item)
325 {
326 extern MemPool *StringPool;
327 assert(item && item->pool);
328 if (StringPool == item->pool)
329 return memStringFree(item->pool, item->my_ptr, item->size);
330 else
331 return memFree(item->pool, item->my_ptr);
332 }
333
334 void
335 my_free(char *file, int line, void *ptr)
336 {
337 #if 0
338 fprintf(stderr, "{%s:%d:%p", file, line, ptr);
339 #endif
340 free(ptr);
341 #if 0
342 fprintf(stderr, "}\n");
343 #endif
344 }
345