void runloops(long sleep_cnt, int num_chunks ) { int cblks ; int victim ; int blk_size ; long ticks_per_sec ; long start_cnt, end_cnt ; _int64 ticks ; double duration ; double reqd_space ; ptrdiff_t used_space ; int sum_allocs=0 ; QueryPerformanceFrequency( &ticks_per_sec ) ; QueryPerformanceCounter( &start_cnt) ; for( cblks=0; cblks<num_chunks; cblks++){ if (max_size == min_size) { blk_size = min_size; } else { blk_size = min_size+lran2(&rgen)%(max_size - min_size) ; } blkp[cblks] = (char *) mm_malloc(blk_size) ; blksize[cblks] = blk_size ; assert(blkp[cblks] != NULL) ; } while(TRUE){ for( cblks=0; cblks<num_chunks; cblks++){ victim = lran2(&rgen)%num_chunks ; mm_free(blkp[victim]) ; if (max_size == min_size) { blk_size = min_size; } else { blk_size = min_size+lran2(&rgen)%(max_size - min_size) ; } blkp[victim] = (char *) mm_malloc(blk_size) ; blksize[victim] = blk_size ; assert(blkp[victim] != NULL) ; } sum_allocs += num_chunks ; QueryPerformanceCounter( &end_cnt) ; ticks = end_cnt - start_cnt ; duration = (double)ticks/ticks_per_sec ; if( duration >= sleep_cnt) break ; } reqd_space = (0.5*(min_size+max_size)*num_chunks) ; used_space = mem_usage(); printf("%6.3f", duration ) ; printf("%8.0f", sum_allocs/duration ) ; printf(" %6.3f %.3f", (double)used_space/(1024*1024), used_space/reqd_space) ; printf("\n") ; }
static void warmup(char **blkp, int num_chunks ) { int cblks ; int victim ; int blk_size ; LPVOID tmp ; for( cblks=0; cblks<num_chunks; cblks++){ if (min_size == max_size) { blk_size = min_size; } else { blk_size = min_size+lran2(&rgen)%(max_size-min_size) ; } #ifdef CPP blkp[cblks] = new char[blk_size] ; #else blkp[cblks] = (char *) malloc(blk_size) ; #endif blksize[cblks] = blk_size ; assert(blkp[cblks] != NULL) ; } /* generate a random permutation of the chunks */ for( cblks=num_chunks; cblks > 0 ; cblks--){ victim = lran2(&rgen)%cblks ; tmp = blkp[victim] ; blkp[victim] = blkp[cblks-1] ; blkp[cblks-1] = (char *) tmp ; } for( cblks=0; cblks<4*num_chunks; cblks++){ victim = lran2(&rgen)%num_chunks ; #ifdef CPP delete blkp[victim] ; #else free(blkp[victim]) ; #endif if (max_size == min_size) { blk_size = min_size; } else { blk_size = min_size+lran2(&rgen)%(max_size - min_size) ; } #ifdef CPP blkp[victim] = new char[blk_size] ; #else blkp[victim] = (char *) malloc(blk_size) ; #endif blksize[victim] = blk_size ; assert(blkp[victim] != NULL) ; } }
void malloc_test(struct thread_st *st) { struct block *bl; int i, b, r; struct lran2_st ld; /* data for random number generator */ unsigned long rsize[BINS_PER_BLOCK]; int rnum[BINS_PER_BLOCK]; lran2_init(&ld, st->u.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; b<BINS_PER_BLOCK; b++) bin_free(&bl->b[b]); mutex_unlock(&bl->mutex); i += BINS_PER_BLOCK; } else { /* alloc/realloc */ /* Generate random numbers in advance. */ for(b=0; b<BINS_PER_BLOCK; b++) { rsize[b] = RANDOM(&ld, st->u.size) + 1; rnum[b] = lran2(&ld); } mutex_lock(&bl->mutex); for(b=0; b<BINS_PER_BLOCK; b++) bin_alloc(&bl->b[b], rsize[b], rnum[b]); mutex_unlock(&bl->mutex); i += BINS_PER_BLOCK; } #if TEST > 2 bin_test(); #endif } }
void malloc_test(struct thread_st *st) { int b, i, j, actions, pid = 1; struct bin_info p; struct lran2_st ld; /* data for random number generator */ lran2_init(&ld, st->u.seed); #if TEST_FORK>0 if(RANDOM(&ld, TEST_FORK) == 0) { int status; #if !USE_THR pid = fork(); #else pid = fork1(); #endif if(pid > 0) { /*printf("forked, waiting for %d...\n", pid);*/ waitpid(pid, &status, 0); printf("done with %d...\n", pid); if(!WIFEXITED(status)) { printf("child term with signal %d\n", WTERMSIG(status)); exit(1); } return; } exit(0); } #endif p.m = (struct bin *)malloc(st->u.bins*sizeof(*p.m)); p.bins = st->u.bins; p.size = st->u.size; for(b=0; b<p.bins; b++) { p.m[b].size = 0; p.m[b].ptr = NULL; if(RANDOM(&ld, 2) == 0) bin_alloc(&p.m[b], RANDOM(&ld, p.size) + 1, lran2(&ld)); } for(i=0; i<=st->u.max;) { #if TEST > 1 bin_test(&p); #endif actions = RANDOM(&ld, ACTIONS_MAX); #if USE_MALLOC && MALLOC_DEBUG if(actions < 2) { mallinfo(); } #endif for(j=0; j<actions; j++) { b = RANDOM(&ld, p.bins); bin_free(&p.m[b]); } i += actions; actions = RANDOM(&ld, ACTIONS_MAX); for(j=0; j<actions; j++) { b = RANDOM(&ld, p.bins); bin_alloc(&p.m[b], RANDOM(&ld, p.size) + 1, lran2(&ld)); #if TEST > 2 bin_test(&p); #endif } #if 0 /* Test illegal free()s while setting MALLOC_CHECK_ */ for(j=0; j<8; j++) { b = RANDOM(&ld, p.bins); if(p.m[b].ptr) { int offset = (RANDOM(&ld, 11) - 5)*8; char *rogue = (char*)(p.m[b].ptr) + offset; /*printf("p=%p rogue=%p\n", p.m[b].ptr, rogue);*/ free(rogue); } } #endif i += actions; } for(b=0; b<p.bins; b++) bin_free(&p.m[b]); free(p.m); if(pid == 0) exit(0); }
static void * exercise_heap( void *pinput) { thread_data *pdea; int cblks=0 ; int victim ; long blk_size ; int range ; if( stopflag ) return 0; pdea = (thread_data *)pinput ; pdea->finished = FALSE ; pdea->cThreads++ ; range = pdea->max_size - pdea->min_size ; /* allocate NumBlocks chunks of random size */ for( cblks=0; cblks<pdea->NumBlocks; cblks++){ victim = lran2(&pdea->rgen)%pdea->asize ; #ifdef CPP delete pdea->array[victim] ; #else free(pdea->array[victim]) ; #endif pdea->cFrees++ ; if (range == 0) { blk_size = pdea->min_size; } else { blk_size = pdea->min_size+lran2(&pdea->rgen)%range ; } #ifdef CPP pdea->array[victim] = new char[blk_size] ; #else pdea->array[victim] = (char *) malloc(blk_size) ; #endif pdea->blksize[victim] = blk_size ; assert(pdea->array[victim] != NULL) ; pdea->cAllocs++ ; /* Write something! */ volatile char * chptr = ((char *) pdea->array[victim]); *chptr++ = 'a'; volatile char ch = *((char *) pdea->array[victim]); *chptr = 'b'; if( stopflag ) break ; } // printf("Thread %u terminating: %d allocs, %d frees\n", // pdea->threadno, pdea->cAllocs, pdea->cFrees) ; pdea->finished = TRUE ; if( !stopflag ){ #ifdef __WIN32__ _beginthread((void (__cdecl*)(void *)) exercise_heap, 0, pdea) ; #else _beginthread(exercise_heap, 0, pdea) ; #endif } else { printf ("thread stopping.\n"); } #ifndef _WIN32 pthread_exit (NULL); #endif return 0; }
//#ifdef _MT void runthreads(long sleep_cnt, int min_threads, int max_threads, int chperthread, int num_rounds) { thread_data *de_area = new thread_data[max_threads] ; thread_data *pdea; int nperthread ; int sum_threads ; unsigned long sum_allocs ; unsigned long sum_frees ; double duration ; #ifdef __WIN32__ _LARGE_INTEGER ticks_per_sec, start_cnt, end_cnt; #else long ticks_per_sec ; long start_cnt, end_cnt ; #endif _int64 ticks ; double rate_1=0, rate_n ; double reqd_space ; ULONG used_space ; int prevthreads ; int i ; QueryPerformanceFrequency( &ticks_per_sec ) ; pdea = &de_area[0] ; memset(&de_area[0], 0, sizeof(thread_data)) ; prevthreads = 0 ; for(num_threads=min_threads; num_threads <= max_threads; num_threads++ ) { warmup(&blkp[prevthreads*chperthread], (num_threads-prevthreads)*chperthread ); nperthread = chperthread ; stopflag = FALSE ; for(i=0; i< num_threads; i++){ de_area[i].threadno = i+1 ; de_area[i].NumBlocks = num_rounds*nperthread; de_area[i].array = &blkp[i*nperthread] ; de_area[i].blksize = &blksize[i*nperthread] ; de_area[i].asize = nperthread ; de_area[i].min_size = min_size ; de_area[i].max_size = max_size ; de_area[i].seed = lran2(&rgen) ; ; de_area[i].finished = 0 ; de_area[i].cAllocs = 0 ; de_area[i].cFrees = 0 ; de_area[i].cThreads = 0 ; de_area[i].finished = FALSE ; lran2_init(&de_area[i].rgen, de_area[i].seed) ; #ifdef __WIN32__ _beginthread((void (__cdecl*)(void *)) exercise_heap, 0, &de_area[i]) ; #else _beginthread(exercise_heap, 0, &de_area[i]) ; #endif } QueryPerformanceCounter( &start_cnt) ; // printf ("Sleeping for %ld seconds.\n", sleep_cnt); Sleep(sleep_cnt * 1000L) ; stopflag = TRUE ; for(i=0; i<num_threads; i++){ while( !de_area[i].finished ){ #ifdef __WIN32__ Sleep(1); #elif defined(__SVR4) thr_yield(); #else sched_yield(); #endif } } QueryPerformanceCounter( &end_cnt) ; sum_frees = sum_allocs =0 ; sum_threads = 0 ; for(i=0;i< num_threads; i++){ sum_allocs += de_area[i].cAllocs ; sum_frees += de_area[i].cFrees ; sum_threads += de_area[i].cThreads ; de_area[i].cAllocs = de_area[i].cFrees = 0; } #ifdef __WIN32__ ticks = end_cnt.QuadPart - start_cnt.QuadPart ; duration = (double)ticks/ticks_per_sec.QuadPart ; #else ticks = end_cnt - start_cnt ; duration = (double)ticks/ticks_per_sec ; #endif for( i=0; i<num_threads; i++){ if( !de_area[i].finished ) printf("Thread at %d not finished\n", i) ; } rate_n = sum_allocs/duration ; if( rate_1 == 0){ rate_1 = rate_n ; } reqd_space = (0.5*(min_size+max_size)*num_threads*chperthread) ; // used_space = CountReservedSpace() - init_space; used_space = 0; printf ("Throughput = %8.0f operations per second.\n", sum_allocs / duration); #if 0 printf("%2d ", num_threads ) ; printf("%6.3f", duration ) ; printf("%6.3f", rate_n/rate_1 ) ; printf("%8.0f", sum_allocs/duration ) ; printf(" %6.3f %.3f", (double)used_space/(1024*1024), used_space/reqd_space) ; printf("\n") ; #endif Sleep(5000L) ; // wait 5 sec for old threads to die prevthreads = num_threads ; printf ("Done sleeping...\n"); } delete [] de_area; }
void runloops(long sleep_cnt, int num_chunks ) { int cblks ; int victim ; int blk_size ; #ifdef __WIN32__ _LARGE_INTEGER ticks_per_sec, start_cnt, end_cnt; #else long ticks_per_sec ; long start_cnt, end_cnt ; #endif _int64 ticks ; double duration ; double reqd_space ; ULONG used_space ; int sum_allocs=0 ; QueryPerformanceFrequency( &ticks_per_sec ) ; QueryPerformanceCounter( &start_cnt) ; for( cblks=0; cblks<num_chunks; cblks++){ if (max_size == min_size) { blk_size = min_size; } else { blk_size = min_size+lran2(&rgen)%(max_size - min_size) ; } #ifdef CPP blkp[cblks] = new char[blk_size] ; #else blkp[cblks] = (char *) malloc(blk_size) ; #endif blksize[cblks] = blk_size ; assert(blkp[cblks] != NULL) ; } while(TRUE){ for( cblks=0; cblks<num_chunks; cblks++){ victim = lran2(&rgen)%num_chunks ; #ifdef CPP delete blkp[victim] ; #else free(blkp[victim]) ; #endif if (max_size == min_size) { blk_size = min_size; } else { blk_size = min_size+lran2(&rgen)%(max_size - min_size) ; } #ifdef CPP blkp[victim] = new char[blk_size] ; #else blkp[victim] = (char *) malloc(blk_size) ; #endif blksize[victim] = blk_size ; assert(blkp[victim] != NULL) ; } sum_allocs += num_chunks ; QueryPerformanceCounter( &end_cnt) ; #ifdef __WIN32__ ticks = end_cnt.QuadPart - start_cnt.QuadPart ; duration = (double)ticks/ticks_per_sec.QuadPart ; #else ticks = end_cnt - start_cnt ; duration = (double)ticks/ticks_per_sec ; #endif if( duration >= sleep_cnt) break ; } reqd_space = (0.5*(min_size+max_size)*num_chunks) ; // used_space = CountReservedSpace() - init_space; printf("%6.3f", duration ) ; printf("%8.0f", sum_allocs/duration ) ; printf(" %6.3f %.3f", (double)used_space/(1024*1024), used_space/reqd_space) ; printf("\n") ; }
static void * exercise_heap( void *pinput) { thread_data *pdea; int cblks=0 ; int victim ; long blk_size ; int range ; if( stopflag ) { printf("thread %u stopping immediately\n",((thread_data *)pinput)->threadno); return 0; } pdea = (thread_data *)pinput ; setCPU(pdea->threadno % numCPU); /*printf("Thread %u starting exercise, nthreads=%d\n",pdea->threadno,pdea->cThreads) ;*/ pdea->finished = FALSE ; pdea->cThreads++ ; range = pdea->max_size - pdea->min_size ; /* allocate NumBlocks chunks of random size */ for( cblks=0; cblks<pdea->NumBlocks; cblks++){ victim = lran2(&pdea->rgen)%pdea->asize ; mm_free(pdea->array[victim]) ; pdea->cFrees++ ; if (range == 0) { blk_size = pdea->min_size; } else { blk_size = pdea->min_size+lran2(&pdea->rgen)%range ; } pdea->array[victim] = (char *) mm_malloc(blk_size) ; pdea->blksize[victim] = blk_size ; assert(pdea->array[victim] != NULL) ; pdea->cAllocs++ ; /* Write something! */ volatile char * chptr = ((char *) pdea->array[victim]); *chptr++ = 'a'; volatile char ch = *((char *) pdea->array[victim]); (void)ch; *chptr = 'b'; if( stopflag ) break ; } //printf("Thread %u terminating: %d allocs, %d frees\n", // pdea->threadno, pdea->cAllocs, pdea->cFrees) ; pdea->finished = TRUE ; if( !stopflag ){ _beginthread(exercise_heap, 0, pdea) ; } else { printf ("thread stopping.\n"); } pthread_exit (NULL); return 0; }
void runthreads(long sleep_cnt, int min_threads, int max_threads, int chperthread, int num_rounds) { thread_data de_area[MAX_THREADS] ; int nperthread ; int sum_threads ; int sum_allocs ; int sum_frees ; double duration ; long ticks_per_sec ; long start_cnt, end_cnt ; _int64 ticks ; double rate_1=0, rate_n ; double reqd_space ; ptrdiff_t used_space ; int prevthreads ; int i ; QueryPerformanceFrequency( &ticks_per_sec ) ; memset(&de_area[0], 0, sizeof(thread_data)) ; prevthreads = 0 ; for(num_threads=min_threads; num_threads <= max_threads; num_threads++ ) { warmup(&blkp[prevthreads*chperthread], (num_threads-prevthreads)*chperthread ); nperthread = chperthread ; stopflag = FALSE ; for(i=0; i< num_threads; i++){ de_area[i].threadno = i+1 ; de_area[i].NumBlocks = num_rounds*nperthread; de_area[i].array = &blkp[i*nperthread] ; de_area[i].blksize = &blksize[i*nperthread] ; de_area[i].asize = nperthread ; de_area[i].min_size = min_size ; de_area[i].max_size = max_size ; de_area[i].seed = lran2(&rgen) ; ; de_area[i].finished = 0 ; de_area[i].cAllocs = 0 ; de_area[i].cFrees = 0 ; de_area[i].cThreads = 0 ; de_area[i].finished = FALSE ; lran2_init(&de_area[i].rgen, de_area[i].seed) ; _beginthread(exercise_heap, 0, &de_area[i]) ; } QueryPerformanceCounter( &start_cnt) ; //printf ("Sleeping for %ld seconds.\n", sleep_cnt); Sleep(sleep_cnt * 1000L) ; stopflag = TRUE ; for(i=0; i<num_threads; i++){ while( !de_area[i].finished ){ sched_yield(); } } QueryPerformanceCounter( &end_cnt) ; sum_frees = sum_allocs =0 ; sum_threads = 0 ; for(i=0;i< num_threads; i++){ sum_allocs += de_area[i].cAllocs ; sum_frees += de_area[i].cFrees ; sum_threads += de_area[i].cThreads ; printf("area %d: %d allocs, %d threads\n",i,de_area[i].cAllocs,de_area[i].cThreads); de_area[i].cAllocs = de_area[i].cFrees = 0; } ticks = end_cnt - start_cnt ; duration = (double)ticks/ticks_per_sec ; for( i=0; i<num_threads; i++){ if( !de_area[i].finished ) printf("Thread at %d not finished\n", i) ; } rate_n = sum_allocs/duration ; if( rate_1 == 0){ rate_1 = rate_n ; } reqd_space = (0.5*(min_size+max_size)*num_threads*chperthread) ; used_space = mem_usage(); printf ("Throughput = %8.0f operations per second.\n", sum_allocs / duration); printf ("Memory used = %ld bytes, required %.0lf, ratio %lf\n",used_space,reqd_space,used_space/reqd_space); #if 0 printf("%2d ", num_threads ) ; printf("%6.3f", duration ) ; printf("%6.3f", rate_n/rate_1 ) ; printf("%8.0f", sum_allocs/duration ) ; printf(" %6.3f %.3f", (double)used_space/(1024*1024), used_space/reqd_space) ; printf("\n") ; #endif Sleep(5000L) ; // wait 5 sec for old threads to die prevthreads = num_threads ; printf ("Done sleeping...\n"); } }