source: trunk/src/t-test0.c@ 487

Last change on this file since 487 was 481, checked in by katerina, 9 years ago

Enhancements and fixes for tickets #374, #375, #376, #377, #378, and #379.

File size: 9.8 KB
Line 
1/*
2* Copyright (c) 1996-1999, 2001-2004 Wolfram Gloger
3
4Permission to use, copy, modify, distribute, and sell this software
5and its documentation for any purpose is hereby granted without fee,
6provided that (i) the above copyright notices and this permission
7notice appear in all copies of the software and related documentation,
8and (ii) the name of Wolfram Gloger may not be used in any advertising
9or publicity relating to the software.
10
11THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
12EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
13WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
14
15IN NO EVENT SHALL WOLFRAM GLOGER BE LIABLE FOR ANY SPECIAL,
16INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY
17DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY
19OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20PERFORMANCE OF THIS SOFTWARE.
21*/
22
23/*
24 * $Id: t-test1.c,v 1.2 2004/11/04 14:58:45 wg Exp $
25 * by Wolfram Gloger 1996-1999, 2001, 2004
26 * A multi-thread test for malloc performance, maintaining one pool of
27 * allocated bins per thread.
28 */
29/*
30 t-test[12] <n-total> <n-parallel> <n-allocs> <size-max> <bins>
31
32 n-total = total number of threads executed (default 10)
33 n-parallel = number of threads running in parallel (2)
34 n-allocs = number of malloc()'s / free()'s per thread (10000)
35 size-max = max. size requested with malloc() in bytes (10000)
36 bins = number of bins to maintain
37*/
38
39#if defined(HAVE_CONFIG_H)
40#include "config.h"
41#endif
42
43#if (defined __STDC__ && __STDC__) || defined __cplusplus
44# include <stdlib.h>
45#endif
46#include <stdio.h>
47#include <string.h>
48#include <unistd.h>
49#include <sys/types.h>
50#include <sys/time.h>
51#include <sys/resource.h>
52#include <sys/wait.h>
53#include <sys/mman.h>
54
55/*
56#if !USE_MALLOC
57#include <malloc.h>
58#else
59#include "malloc.h"
60#endif
61*/
62
63#ifdef USE_SYSTEM_MALLOC
64extern void *memalign(size_t boundary, size_t size);
65/* #define memalign(a,b) malloc(b) */
66#else
67extern void *memalign(size_t boundary, size_t size);
68#endif
69
70static int verbose = 1;
71
72/* dummy for the samhain safe_fatal logger
73 */
74void safe_fatal(const char * details,
75 const char * file, int line)
76{
77 (void) file;
78 (void) line;
79 fputs("assert failed: ", stderr);
80 puts(details);
81 _exit(EXIT_FAILURE);
82}
83
84/* lran2.h
85 * by Wolfram Gloger 1996.
86 *
87 * A small, portable pseudo-random number generator.
88 */
89
90#ifndef _LRAN2_H
91#define _LRAN2_H
92
93#define LRAN2_MAX 714025l /* constants for portable */
94#define IA 1366l /* random number generator */
95#define IC 150889l /* (see e.g. `Numerical Recipes') */
96
97struct lran2_st {
98 long x, y, v[97];
99};
100
101static void
102lran2_init(struct lran2_st* d, long seed)
103{
104 long x;
105 int j;
106
107 x = (IC - seed) % LRAN2_MAX;
108 if(x < 0) x = -x;
109 for(j=0; j<97; j++) {
110 x = (IA*x + IC) % LRAN2_MAX;
111 d->v[j] = x;
112 }
113 d->x = (IA*x + IC) % LRAN2_MAX;
114 d->y = d->x;
115}
116
117#ifdef __GNUC__
118__inline__
119#endif
120static long
121lran2(struct lran2_st* d)
122{
123 int j = (d->y % 97);
124
125 d->y = d->v[j];
126 d->x = (IA*d->x + IC) % LRAN2_MAX;
127 d->v[j] = d->x;
128 return d->y;
129}
130
131#undef IA
132#undef IC
133
134#endif
135
136/*
137 * $Id: t-test.h,v 1.1 2004/11/04 14:32:21 wg Exp $
138 * by Wolfram Gloger 1996.
139 * Common data structures and functions for testing malloc performance.
140 */
141
142/* Testing level */
143#ifndef TEST
144#define TEST 99
145#endif
146
147/* For large allocation sizes, the time required by copying in
148 realloc() can dwarf all other execution times. Avoid this with a
149 size threshold. */
150#ifndef REALLOC_MAX
151#define REALLOC_MAX 2000
152#endif
153
154struct bin {
155 unsigned char *ptr;
156 unsigned long size;
157};
158
159#if TEST > 0
160
161static void
162mem_init(unsigned char *ptr, unsigned long size)
163{
164 unsigned long i, j;
165
166 if(size == 0) return;
167#if TEST > 3
168 memset(ptr, '\0', size);
169#endif
170 for(i=0; i<size; i+=2047) {
171 j = (unsigned long)ptr ^ i;
172 ptr[i] = ((j ^ (j>>8)) & 0xFF);
173 }
174 j = (unsigned long)ptr ^ (size-1);
175 ptr[size-1] = ((j ^ (j>>8)) & 0xFF);
176}
177
178static int
179mem_check(unsigned char *ptr, unsigned long size)
180{
181 unsigned long i, j;
182
183 if(size == 0) return 0;
184 for(i=0; i<size; i+=2047) {
185 j = (unsigned long)ptr ^ i;
186 if(ptr[i] != ((j ^ (j>>8)) & 0xFF)) return 1;
187 }
188 j = (unsigned long)ptr ^ (size-1);
189 if(ptr[size-1] != ((j ^ (j>>8)) & 0xFF)) return 2;
190 return 0;
191}
192
193static int
194zero_check(unsigned* ptr, unsigned long size)
195{
196 unsigned char* ptr2;
197
198 while(size >= sizeof(*ptr)) {
199 if(*ptr++ != 0)
200 return -1;
201 size -= sizeof(*ptr);
202 }
203 ptr2 = (unsigned char*)ptr;
204 while(size > 0) {
205 if(*ptr2++ != 0)
206 return -1;
207 --size;
208 }
209 return 0;
210}
211
212#endif /* TEST > 0 */
213
214/* Allocate a bin with malloc(), realloc() or memalign(). r must be a
215 random number >= 1024. */
216int n_malloc=0, n_memalign=0, n_realloc=0, n_calloc=0;
217
218static void
219bin_alloc(struct bin *m, unsigned long size, int r)
220{
221#if TEST > 0
222 if(mem_check(m->ptr, m->size)) {
223 fprintf(stderr, "memory corrupt!\n");
224 exit(1);
225 }
226#endif
227 r %= 1024;
228 /*printf("%d ", r);*/
229 if(r < 4) { /* memalign */
230 if(m->size > 0) free(m->ptr);
231 m->ptr = (unsigned char *)memalign(sizeof(int) << r, size);
232 ++n_memalign;
233 } else if(r < 20) { /* calloc */
234 if(m->size > 0) free(m->ptr);
235 m->ptr = (unsigned char *)calloc(size, 1);
236#if TEST > 0
237 if(zero_check((unsigned*)m->ptr, size)) {
238 unsigned long i;
239 for(i=0; i<size; i++)
240 if(m->ptr[i] != 0)
241 break;
242 fprintf(stderr, "calloc'ed memory non-zero (ptr=%p, i=%ld)!\n", m->ptr, i);
243 exit(1);
244 }
245#endif
246 ++n_calloc;
247 } else if(r < 100 && m->size < REALLOC_MAX) { /* realloc */
248 if(m->size == 0) m->ptr = NULL;
249 m->ptr = realloc(m->ptr, size);
250 ++n_realloc;
251 } else { /* plain malloc */
252 if(m->size > 0) free(m->ptr);
253 m->ptr = (unsigned char *)malloc(size);
254 ++n_malloc;
255 }
256 if(!m->ptr) {
257 fprintf(stderr, "out of memory (r=%d, size=%ld)!\n", r, (long)size);
258 exit(1);
259 }
260 m->size = size;
261#if TEST > 0
262 mem_init(m->ptr, m->size);
263#endif
264}
265
266/* Free a bin. */
267
268static void
269bin_free(struct bin *m)
270{
271 if(m->size == 0) return;
272#if TEST > 0
273 if(mem_check(m->ptr, m->size)) {
274 fprintf(stderr, "memory corrupt!\n");
275 exit(1);
276 }
277#endif
278 free(m->ptr);
279 m->size = 0;
280}
281
282/*
283 * Local variables:
284 * tab-width: 4
285 * End:
286 */
287
288
289struct user_data {
290 int bins, max;
291 unsigned long size;
292 long seed;
293};
294
295/*
296 * $Id: thread-st.h$
297 * pthread version
298 * by Wolfram Gloger 2004
299 */
300
301#include <pthread.h>
302#include <stdio.h>
303
304pthread_cond_t finish_cond = PTHREAD_COND_INITIALIZER;
305pthread_mutex_t finish_mutex = PTHREAD_MUTEX_INITIALIZER;
306
307#ifndef USE_PTHREADS_STACKS
308#define USE_PTHREADS_STACKS 0
309#endif
310
311#ifndef STACKSIZE
312#define STACKSIZE 32768
313#endif
314
315
316
317
318/*
319 * Local variables:
320 * tab-width: 4
321 * End:
322 */
323
324
325#define N_TOTAL 10
326#ifndef N_THREADS
327#define N_THREADS 2
328#endif
329#ifndef N_TOTAL_PRINT
330#define N_TOTAL_PRINT 50
331#endif
332#ifndef MEMORY
333#define MEMORY 8000000l
334#endif
335#define SIZE 10000
336#define I_MAX 10000
337#define ACTIONS_MAX 30
338#ifndef TEST_FORK
339#define TEST_FORK 0
340#endif
341
342#define RANDOM(d,s) (lran2(d) % (s))
343
344struct bin_info {
345 struct bin *m;
346 unsigned long size, bins;
347};
348
349#if TEST > 0
350
351void
352bin_test(struct bin_info *p)
353{
354 unsigned int b;
355
356 for(b=0; b<p->bins; b++) {
357 if(mem_check(p->m[b].ptr, p->m[b].size)) {
358 fprintf(stderr, "memory corrupt!\n");
359 abort();
360 }
361 }
362}
363
364#endif
365
366void
367malloc_test(unsigned long size, int bins, int max)
368{
369 unsigned int b;
370 int i, j, actions;
371 struct bin_info p;
372 struct lran2_st ld; /* data for random number generator */
373
374 lran2_init(&ld, ((long)max*size + getpid()) ^ bins);
375
376 p.m = (struct bin *)malloc(bins*sizeof(*p.m));
377 p.bins = bins;
378 p.size = size;
379
380 for(b=0; b<p.bins; b++) {
381 p.m[b].size = 0;
382 p.m[b].ptr = NULL;
383 if(RANDOM(&ld, 2) == 0)
384 bin_alloc(&p.m[b], RANDOM(&ld, p.size) + 1, lran2(&ld));
385 }
386 for(i=0; i<=max;) {
387#if TEST > 1
388 bin_test(&p);
389#endif
390 actions = RANDOM(&ld, ACTIONS_MAX);
391#if USE_MALLOC && MALLOC_DEBUG
392 if(actions < 2) { mallinfo(); }
393#endif
394 for(j=0; j<actions; j++) {
395 b = RANDOM(&ld, p.bins);
396 bin_free(&p.m[b]);
397 }
398 i += actions;
399 actions = RANDOM(&ld, ACTIONS_MAX);
400 for(j=0; j<actions; j++) {
401 b = RANDOM(&ld, p.bins);
402 bin_alloc(&p.m[b], RANDOM(&ld, p.size) + 1, lran2(&ld));
403#if TEST > 2
404 bin_test(&p);
405#endif
406 }
407
408 i += actions;
409 }
410 for(b=0; b<p.bins; b++)
411 bin_free(&p.m[b]);
412 free(p.m);
413 return;
414}
415
416int n_total=0, n_total_max=N_TOTAL, n_running;
417
418int
419main(int argc, char *argv[])
420{
421 int bins;
422 int n_thr=N_THREADS;
423 int i_max=I_MAX;
424 unsigned long size=SIZE;
425
426#if USE_MALLOC && USE_STARTER==2
427 ptmalloc_init();
428 printf("ptmalloc_init\n");
429#endif
430
431 if((argc > 1) && (0 == strcmp(argv[1], "-h") || 0 == strcmp(argv[1], "--help")))
432 {
433 printf("%s <n-total> <n-parallel> <n-allocs> <size-max> <bins>\n\n", argv[0]);
434 printf(" n-total = total number of threads executed (default 10)\n");
435 printf(" UNUSED n-parallel = number of threads running in parallel (2)\n");
436 printf(" n-allocs = number of malloc()'s / free()'s per thread (10000)\n");
437 printf(" size-max = max. size requested with malloc() in bytes (10000)\n");
438 printf(" bins = number of bins to maintain\n");
439 return 0;
440 }
441
442 if(argc > 1) n_total_max = atoi(argv[1]);
443 if(n_total_max < 1) n_thr = 1;
444 if(argc > 2) n_thr = atoi(argv[2]);
445 if(n_thr < 1) n_thr = 1;
446 if(n_thr > 100) n_thr = 100;
447 if(argc > 3) i_max = atoi(argv[3]);
448
449 if(argc > 4) size = atol(argv[4]);
450 if(size < 2) size = 2;
451
452 bins = MEMORY/(size*n_thr);
453 if(argc > 5) bins = atoi(argv[5]);
454 if(bins < 4) bins = 4;
455
456 printf("[total=%d threads=%d] i_max=%d size=%ld bins=%d\n",
457 n_total_max, n_thr, i_max, size, bins);
458
459 do {
460 n_total++;
461 malloc_test(size, bins, i_max);
462 if (verbose)
463 if(n_total%N_TOTAL_PRINT == 0)
464 printf("n_total = %8d - malloc %12d / memalign %12d / realloc %12d / calloc %12d\n",
465 n_total,
466 n_malloc, n_memalign, n_realloc, n_calloc);
467 } while (n_total < n_total_max);
468
469
470#if USE_MALLOC
471 malloc_stats();
472#endif
473 if (verbose)
474 printf("Done.\n");
475 return 0;
476}
477
478/*
479 * Local variables:
480 * tab-width: 4
481 * End:
482 */
Note: See TracBrowser for help on using the repository browser.