/* * $Id: t-test2.c,v 1.3 2004/11/04 15:01:05 wg Exp $ * by Wolfram Gloger 1996-1999, 2001, 2004 * A multi-thread test for malloc performance, maintaining a single * global pool of allocated bins. */ #if (defined __STDC__ && __STDC__) || defined __cplusplus # include #endif #include #include #include #include #include #include #if !USE_MALLOC #include #else #include "malloc.h" #endif #include "lran2.h" #include "t-test.h" struct user_data { int max; unsigned long size; long seed; }; #include "thread-st.h" #include "malloc-machine.h" /* for mutex */ #define N_TOTAL 10 #ifndef N_THREADS #define N_THREADS 2 #endif #ifndef N_TOTAL_PRINT #define N_TOTAL_PRINT 50 #endif #define STACKSIZE 32768 #ifndef MEMORY #define MEMORY 8000000l #endif #define SIZE 10000 #define I_MAX 10000 #define BINS_PER_BLOCK 20 #define RANDOM(d,s) (lran2(d) % (s)) struct block { struct bin b[BINS_PER_BLOCK]; mutex_t mutex; } *blocks; int n_blocks; #if TEST > 0 void bin_test(void) { int b, i; for(b=0; bu.seed); for(i=0; i<=st->u.max;) { #if TEST > 1 bin_test(); #endif bl = &blocks[RANDOM(&ld, n_blocks)]; r = RANDOM(&ld, 1024); if(r < 200) { /* free only */ mutex_lock(&bl->mutex); for(b=0; bb[b]); mutex_unlock(&bl->mutex); i += BINS_PER_BLOCK; } else { /* alloc/realloc */ /* Generate random numbers in advance. */ for(b=0; bu.size) + 1; rnum[b] = lran2(&ld); } mutex_lock(&bl->mutex); for(b=0; bb[b], rsize[b], rnum[b]); mutex_unlock(&bl->mutex); i += BINS_PER_BLOCK; } #if TEST > 2 bin_test(); #endif } } int n_total=0, n_total_max=N_TOTAL, n_running; int my_end_thread(struct thread_st *st) { /* Thread st has finished. Start a new one. */ #if 0 printf("Thread %lx terminated.\n", (long)st->id); #endif if(n_total >= n_total_max) { n_running--; } else if(st->u.seed++, thread_create(st)) { printf("Creating thread #%d failed.\n", n_total); } else { n_total++; if(n_total%N_TOTAL_PRINT == 0) printf("n_total = %d\n", n_total); } return 0; } int main(int argc, char *argv[]) { int i, j, bins; int n_thr=N_THREADS; int i_max=I_MAX; unsigned long size=SIZE; struct thread_st *st; #if USE_MALLOC && USE_STARTER==2 ptmalloc_init(); printf("ptmalloc_init\n"); #endif if(argc > 1) n_total_max = atoi(argv[1]); if(n_total_max < 1) n_thr = 1; if(argc > 2) n_thr = atoi(argv[2]); if(n_thr < 1) n_thr = 1; if(n_thr > 100) n_thr = 100; if(argc > 3) i_max = atoi(argv[3]); if(argc > 4) size = atol(argv[4]); if(size < 2) size = 2; bins = MEMORY/size; if(argc > 5) bins = atoi(argv[5]); if(bins < BINS_PER_BLOCK) bins = BINS_PER_BLOCK; n_blocks = bins/BINS_PER_BLOCK; blocks = (struct block *)malloc(n_blocks*sizeof(*blocks)); if(!blocks) exit(1); thread_init(); printf("total=%d threads=%d i_max=%d size=%ld bins=%d\n", n_total_max, n_thr, i_max, size, n_blocks*BINS_PER_BLOCK); for(i=0; i0;) { wait_for_thread(st, n_thr, my_end_thread); } for(i=0; i