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

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

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

File size: 9.8 KB
RevLine 
[481]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.