usermode/library/malloc-original/benchmarks/larson/driver_mt.c

00001 #include  <stdio.h>
00002 #include  <stdlib.h>
00003 #include  <stddef.h>
00004 #include  <string.h>
00005 #include  <ctype.h>
00006 #include  <time.h>
00007 
00008 #ifdef __WIN32__
00009 #include  <conio.h>
00010 #include  <crtdbg.h>
00011 #include  <process.h>
00012 #include  <windows.h>
00013 #else
00014 typedef void * LPVOID;
00015 typedef long long LONGLONG;
00016 typedef long DWORD;
00017 typedef long LONG;
00018 typedef union _LARGE_INTEGER {
00019   struct {
00020     DWORD LowPart;
00021     LONG  HighPart;
00022   };
00023   LONGLONG QuadPart;    // In Visual C++, a typedef to _ _int64} LARGE_INTEGER;
00024 } LARGE_INTEGER;
00025 typedef long long _int64;
00026 enum { TRUE = 1, FALSE = 0 };
00027 #include <assert.h>
00028 #define _ASSERTE(x) assert(x)
00029 #define pt_malloc_init(x)
00030 void * pt_malloc (int x)
00031 {
00032   return malloc(x);
00033 }
00034 
00035 #define pt_free(x) free(x)
00036 void Sleep (long x) 
00037 {
00038   printf ("sleeping for %d seconds.\n", x/1000);
00039   sleep(x/1000);
00040 }
00041 
00042 #define QueryPerformanceCounter(x) times(0)
00043 #define QueryPerformanceFrequency(x) CLK_TCK
00044 
00045 #define _REENTRANT 1
00046 #include <pthread.h>
00047 typedef void * VoidFunction (void *);
00048 void _beginthread (VoidFunction x, int y, void * z)
00049 {
00050   pthread_t pt;
00051   printf ("creating a thread.\n");
00052   pthread_create(&pt, NULL, x, z);
00053 }
00054 #endif
00055 
00056 #include  "perfcounters.h"
00057 /* #include  "ptmalloc.h" */
00058 
00059 
00060 /* Test driver for memory allocators           */
00061 /* Author: Paul Larson, palarson@microsoft.com */
00062 
00063 #define MAX_THREADS     100
00064 #define MAX_BLOCKS  1000000
00065 #define MAX_IIV           1
00066 
00067 #define TC_CONTINUE          0
00068 #define TC_PAUSE             1
00069 #define TC_TERMINATE         2
00070 
00071 struct lran2_st {
00072   long x, y, v[97];
00073 };
00074 
00075 typedef struct thr_data {
00076 
00077   int    threadno ;
00078   int    NumBlocks ;
00079   int    seed ;
00080 
00081   int    min_size ;
00082   int    max_size ;
00083 
00084   LPVOID *array ;
00085   int     asize ;
00086 
00087   int    cAllocs ;
00088   int    cFrees ;
00089   int    cThreads ;
00090 
00091   PerfCounters  cntrs ;
00092 
00093   int    waitflag ;       
00094   int    finished ;
00095   struct lran2_st rgen ;
00096 
00097 } thread_data;
00098 
00099 
00100 static void warmup(LPVOID *blkp, int num_chunks, thread_data *pdea );
00101 static void * exercise_heap( void *pinput) ;
00102 static void lran2_init(struct lran2_st* d, long seed) ;
00103 static long lran2(struct lran2_st* d) ;
00104  
00105 LPVOID        blkp[MAX_BLOCKS] ;
00106 long          seqlock=0 ;
00107 int           min_size, max_size ;
00108 struct lran2_st rgen ;
00109 
00110 extern  int   cAllocedChunks ;
00111 extern  int   cAllocedSpace ;
00112 extern  int   cUsedSpace ;
00113 extern  int   cFreeChunks ;
00114 extern  int   cFreeSpace ;
00115 
00116 int main()
00117 {
00118   thread_data  de_area[MAX_THREADS] ;
00119   thread_data *pdea;
00120   int          min_threads, max_threads ;
00121   int          num_threads, prevthreads ;
00122   unsigned     seed=12345 ;
00123   int          sum_allocs ;
00124   int          sum_frees ;
00125   double       duration ;
00126   char        *allocator ;
00127   int          ii, i ;
00128 
00129   LPVOID        tmp ;
00130   int           cblks=0 ;
00131   int           victim ;
00132   long          blk_size ;
00133   int           nperthread ;
00134   int           chperthread ;
00135   int           num_chunks;
00136   int           num_rounds ;
00137   int           sum_threads ;
00138   /*    struct mallinfo cur_mallinfo ; */
00139   LARGE_INTEGER ticks_per_sec ;
00140   LARGE_INTEGER start_cnt, end_cnt ;
00141   _int64        ticks ;
00142   double        rate_1=0, rate_n ;
00143   double        eused_space ;
00144 
00145 
00146 
00147   printf( "\nTest driver for memory allocators \n") ;
00148 # ifdef WIN32_CRITICAL_SECTIONS
00149   allocator = "PT_MALLOC with WIN32 critical sections" ;
00150 # else
00151   allocator = "PT_MALLOC with spin locks" ;
00152 # endif
00153 
00154   printf("Using %s,\n\n", allocator ) ;
00155   printf("chunk size (min,max): ") ;
00156   scanf("%d %d", &min_size, &max_size ) ;
00157   printf("threads (min, max):   ") ; 
00158   scanf("%d %d", &min_threads, &max_threads) ;
00159   printf("chunks/thread: ") ; scanf("%d", &chperthread ) ;
00160   printf("no of rounds:  ") ; scanf("%d", &num_rounds ) ;
00161   printf("random seed: ") ;   scanf("%d", &seed) ;
00162 
00163   num_chunks = max_threads*chperthread ;
00164   if( num_chunks > MAX_BLOCKS ){
00165     printf("Max %d chunks - exiting\n", MAX_BLOCKS ) ;
00166     return(1) ;
00167   }
00168 
00169   lran2_init(&rgen, seed) ;
00170   pt_malloc_init(void) ;
00171 
00172   QueryPerformanceFrequency( &ticks_per_sec ) ;
00173 
00174   pdea = &de_area[0] ;
00175   memset(&de_area[0], 0, sizeof(thread_data)) ;
00176 
00177   prevthreads = 0 ;
00178 
00179   for(num_threads=min_threads; num_threads <= max_threads; num_threads++ )
00180     {
00181 
00182       nperthread = chperthread ;
00183       warmup(&blkp[prevthreads*chperthread], (num_threads-prevthreads)*chperthread, pdea );
00184                 
00185       for(i=0; i< num_threads; i++){
00186         de_area[i].threadno    = i+1 ;
00187         de_area[i].NumBlocks   = num_rounds*nperthread;
00188         de_area[i].array       = &blkp[i*nperthread] ;
00189         de_area[i].asize       = nperthread ;
00190         de_area[i].min_size    = min_size ;
00191         de_area[i].max_size    = max_size ;
00192         de_area[i].seed        = lran2(&rgen) ; ;
00193         de_area[i].finished    = 0 ;
00194         de_area[i].cAllocs     = 0 ;
00195         de_area[i].cFrees      = 0 ;
00196         de_area[i].cThreads    = 0 ;
00197         de_area[i].waitflag    = TC_CONTINUE ;
00198         de_area[i].finished    = FALSE ;
00199         memset(&de_area[i].cntrs, 0, sizeof(PerfCounters)) ;
00200         lran2_init(&de_area[i].rgen, de_area[i].seed) ;
00201 
00202         _beginthread(exercise_heap, 0, &de_area[i]) ;  
00203       }
00204 
00205       for(ii=0; ii<MAX_IIV ; ii++) {
00206         QueryPerformanceCounter( &start_cnt) ;
00207         
00208         Sleep(30000L) ;
00209         printf ("TIME TO DIE!\n");
00210         
00211         for(i=0; i< num_threads; i++) de_area[i].waitflag = TC_PAUSE ;
00212         
00213         for(i=0; i< num_threads; i++){
00214           while( !de_area[i].finished ){
00215             //Sleep(0) ;
00216           }
00217         }
00218         
00219         QueryPerformanceCounter( &end_cnt) ;
00220         
00221         sum_frees = sum_allocs =0  ;
00222         sum_threads = 0 ;
00223         for(i=0;i< num_threads; i++){
00224           sum_allocs    += de_area[i].cAllocs ;
00225           sum_frees     += de_area[i].cFrees ;
00226           sum_threads   += de_area[i].cThreads ;
00227           de_area[i].cAllocs = de_area[i].cFrees = 0;
00228         }
00229         ticks = end_cnt.QuadPart - start_cnt.QuadPart ;
00230         duration = (double)ticks/ticks_per_sec.QuadPart ;
00231         
00232         rate_n = sum_allocs/duration ;
00233         if( rate_1 == 0){
00234           rate_1 = rate_n ;
00235         }
00236         
00237         //      eused_space = (0.5*(min_size+max_size)*num_chunks) ;
00238         eused_space = (0.5*(min_size+max_size)*num_threads*chperthread) ;
00239         
00240 #if 0
00241         cur_mallinfo = pt_mallinfo() ;
00242 #endif
00243         printf("%2d ", num_threads ) ;
00244         printf("%2d ", ii ) ;
00245         printf("%6.3f", duration  ) ;
00246         printf("%6.3f", rate_n/rate_1 ) ;
00247         printf("%8.0f", sum_allocs/duration ) ;
00248         
00249 #if 0
00250         printf("  %6.2f", (100.0*(double)cur_mallinfo.uordblks)/eused_space ) ;
00251         printf(" %6.2f", (100.0*eused_space)/cur_mallinfo.arena ) ;
00252         //              printf(" %6.2f", (100.0*cur_mallinfo.fordblks)/cur_mallinfo.arena ) ;
00253         printf(" %6d",   cur_mallinfo.ordblks ) ;
00254         printf(" %10d",  cur_mallinfo.arena ) ;
00255 #endif
00256         printf(" %5d",   sum_threads ) ;
00257         
00258         printf("\n") ;
00259         
00260         
00261         for(i=0; i< num_threads; i++){
00262           if( ii == MAX_IIV-1 ) de_area[i].waitflag = TC_TERMINATE ;
00263           else                 de_area[i].waitflag = TC_CONTINUE ;
00264         }
00265 
00266         Sleep(5000L) ; // wait 5 sec for old threads to die
00267       }
00268       prevthreads = num_threads ;
00269 
00270     }
00271 
00272 
00273 #ifdef _DEBUG
00274   _cputs("Hit any key to exit...") ;    (void)_getch() ;
00275 #endif
00276 
00277   return(0) ;
00278 
00279 } /* main */
00280 
00281 
00282 
00283 
00284 static void * exercise_heap( void *pinput)
00285 {
00286   thread_data  *pdea;
00287   int           cblks=0 ;
00288   int           victim ;
00289   long          blk_size ;
00290   int           range ;
00291 
00292   //S_LOCK(&seqlock) ;
00293 
00294   pdea = (thread_data *)pinput ;
00295 BEGIN:
00296   pdea->finished = FALSE ;
00297   pdea->cThreads++ ;
00298   range = pdea->max_size - pdea->min_size ;
00299 
00300   /* allocate NumBlocks chunks of random size */
00301   for( cblks=0; cblks<pdea->NumBlocks; cblks++){
00302     victim = lran2(&pdea->rgen)%pdea->asize ;
00303     pt_free(pdea->array[victim]) ;
00304     pdea->cFrees++ ;
00305 
00306     blk_size = pdea->min_size+lran2(&pdea->rgen)%range ;
00307     pdea->array[victim] = pt_malloc(blk_size) ;
00308     _ASSERTE(pdea->array[victim] != NULL) ;
00309     pdea->cAllocs++ ;
00310   }
00311 
00312   pdea->finished = TRUE ;
00313   while( pdea->waitflag == TC_PAUSE){
00314     Sleep(0) ;
00315   }
00316   if( pdea->waitflag == TC_CONTINUE){
00317     _beginthread(exercise_heap, 0, pdea) ;
00318   }
00319   //    S_UNLOCK(&seqlock) ;
00320 
00321   printf("Thread %u terminating: %d allocs, %d frees\n",
00322          pdea->threadno, pdea->cAllocs, pdea->cFrees) ;
00323 
00324   return (void *) 0;
00325 
00326 }
00327 
00328 static void warmup(LPVOID *blkp, int num_chunks, thread_data *pdea )
00329 {
00330   int     cblks ;
00331   int     victim ;
00332   int     blk_size ;
00333   LPVOID  tmp ;
00334 
00335 
00336   for( cblks=0; cblks<num_chunks; cblks++){
00337     blk_size = min_size+lran2(&rgen)%(max_size-min_size) ;
00338     blkp[cblks] = pt_malloc(blk_size) ;
00339     _ASSERTE(blkp[cblks] != NULL) ;
00340   }
00341 
00342   /* generate a random permutation of the chunks */
00343   for( cblks=num_chunks; cblks > 0 ; cblks--){
00344     victim = lran2(&rgen)%cblks ;
00345     tmp = blkp[victim] ;
00346     blkp[victim]  = blkp[cblks-1] ;
00347     blkp[cblks-1] = tmp ;
00348   }
00349 
00350   for( cblks=0; cblks<4*num_chunks; cblks++){
00351     victim = lran2(&rgen)%num_chunks ;
00352     pt_free(blkp[victim]) ;
00353 
00354     blk_size = min_size+lran2(&rgen)%(max_size - min_size) ;
00355     blkp[victim] = pt_malloc(blk_size) ;
00356     _ASSERTE(blkp[victim] != NULL) ;
00357   }
00358 }
00359 
00360 // =======================================================
00361 
00362 /* lran2.h
00363  * by Wolfram Gloger 1996.
00364  *
00365  * A small, portable pseudo-random number generator.
00366  */
00367 
00368 #ifndef _LRAN2_H
00369 #define _LRAN2_H
00370 
00371 #define LRAN2_MAX 714025l /* constants for portable */
00372 #define IA        1366l   /* random number generator */
00373 #define IC        150889l /* (see e.g. `Numerical Recipes') */
00374 
00375 //struct lran2_st {
00376 //    long x, y, v[97];
00377 //};
00378 
00379 static void
00380 lran2_init(struct lran2_st* d, long seed)
00381 {
00382   long x;
00383   int j;
00384 
00385   x = (IC - seed) % LRAN2_MAX;
00386   if(x < 0) x = -x;
00387   for(j=0; j<97; j++) {
00388     x = (IA*x + IC) % LRAN2_MAX;
00389     d->v[j] = x;
00390   }
00391   d->x = (IA*x + IC) % LRAN2_MAX;
00392   d->y = d->x;
00393 }
00394 
00395 
00396 static long
00397 lran2(struct lran2_st* d)
00398 {
00399   int j = (d->y % 97);
00400 
00401   d->y = d->v[j];
00402   d->x = (IA*d->x + IC) % LRAN2_MAX;
00403   d->v[j] = d->x;
00404   return d->y;
00405 }
00406 
00407 #undef IA
00408 #undef IC
00409 
00410 #endif
00411 
00412 

Generated on Sat Apr 23 11:43:35 2011 for Mnemosyne by  doxygen 1.4.7