nsprpub/lib/tests/arena.c

Wed, 31 Dec 2014 07:16:47 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:16:47 +0100
branch
TOR_BUG_9701
changeset 3
141e0f1194b1
permissions
-rw-r--r--

Revert simplistic fix pending revisit of Mozilla integration attempt.

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 /*
     7 ** File:        arena.c
     8 ** Description: Testing arenas
     9 **
    10 */
    12 #include <string.h>
    13 #include <time.h>
    14 #include <stdlib.h>
    15 #include "nspr.h"
    16 #include "plarena.h"
    17 #include "plgetopt.h"
    19 PRLogModuleInfo *tLM;
    20 PRIntn  threadCount = 0;
    21 PRMonitor   *tMon;
    22 PRBool failed_already = PR_FALSE;
    24 /* Arguments from the command line with default values */
    25 PRIntn debug_mode = 0;
    26 PRIntn  poolMin = 4096;
    27 PRIntn  poolMax = (100 * 4096);
    28 PRIntn  arenaMin = 40;
    29 PRIntn  arenaMax = (100 * 40);
    30 PRIntn  stressIterations = 15;
    31 PRIntn  maxAlloc = (1024 * 1024);
    32 PRIntn  stressThreads = 4;
    34 void DumpAll( void )
    35 {
    36 	return;
    37 }
    39 /*
    40 ** Test Arena allocation.
    41 */
    42 static void ArenaAllocate( void )
    43 {
    44     PLArenaPool ap;
    45     void    *ptr;
    46 	PRInt32	i;
    48     PL_InitArenaPool( &ap, "AllocArena", 2048, sizeof(double));
    49     PR_LOG( tLM, PR_LOG_DEBUG, ("AA, InitPool -- Pool: %p. first: %p, current: %p, size: %d", 
    50         &ap, ap.first, ap.current, ap.arenasize  ));
    52 	for( i = 0; i < 150; i++ )
    53 	{
    54 		PL_ARENA_ALLOCATE( ptr, &ap, 512 );
    55         PR_LOG( tLM, PR_LOG_DEBUG,("AA, after alloc -- Pool: %p. first: %p, current: %p, size: %d", 
    56                &ap, ap.first, ap.current, ap.arenasize  ));
    57 		PR_LOG( tLM, PR_LOG_DEBUG,(
    58 		    "AA -- Pool: %p. alloc: %p ", &ap, ptr ));
    59 	}
    61     PL_FreeArenaPool( &ap );
    63 	for( i = 0; i < 221; i++ )
    64 	{
    65 		PL_ARENA_ALLOCATE( ptr, &ap, 512 );
    66         PR_LOG( tLM, PR_LOG_DEBUG,("AA, after alloc -- Pool: %p. first: %p, current: %p, size: %d", 
    67                &ap, ap.first, ap.current, ap.arenasize  ));
    68 		PR_LOG( tLM, PR_LOG_DEBUG,(
    69 		    "AA -- Pool: %p. alloc: %p ", &ap, ptr ));
    70 	}
    72     PL_FreeArenaPool( &ap );
    74     return;
    75 } /* end ArenaGrow() */
    76 /*
    77 ** Test Arena grow.
    78 */
    79 static void ArenaGrow( void )
    80 {
    81     PLArenaPool ap;
    82     void    *ptr;
    83 	PRInt32	i;
    85     PL_InitArenaPool( &ap, "TheArena", 4096, sizeof(double));
    86     PL_ARENA_ALLOCATE( ptr, &ap, 512 );
    88 	PR_LOG( tLM, PR_LOG_DEBUG, ("Before growth -- Pool: %p. alloc: %p ", &ap, ptr ));
    90 	for( i = 0; i < 10; i++ )
    91 	{
    92 		PL_ARENA_GROW( ptr, &ap, 512, 7000 );
    93 		PR_LOG( tLM, PR_LOG_DEBUG, ("After growth -- Pool: %p. alloc: %p ", &ap, ptr ));
    94 	}
    97     return;
    98 } /* end ArenaGrow() */
   101 /*
   102 ** Test arena Mark and Release.
   103 */
   104 static void MarkAndRelease( void )
   105 {
   106     PLArenaPool ap;
   107     void    *ptr = NULL;
   108     void    *mark0, *mark1;
   109     PRIntn  i;
   111     PL_InitArenaPool( &ap, "TheArena", 4096, sizeof(double));
   112     mark0 = PL_ARENA_MARK( &ap );
   113     PR_LOG( tLM, PR_LOG_DEBUG,
   114         ("mark0. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p, m0: %p", 
   115             &ap, ap.first.next, ap.current, ap.arenasize, ptr, mark0 ));
   117 	for( i = 0; i < 201; i++ )
   118 	{
   119 		PL_ARENA_ALLOCATE( ptr, &ap, 512 );
   120         PR_LOG( tLM, PR_LOG_DEBUG,
   121             ("mr. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", 
   122                 &ap, ap.first.next, ap.current, ap.arenasize, ptr ));
   123 	}
   125     mark1 = PL_ARENA_MARK( &ap );
   126     PR_LOG( tLM, PR_LOG_DEBUG,
   127         ("mark1. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p, m1: %p", 
   128             &ap, ap.first.next, ap.current, ap.arenasize, ptr, mark1 ));
   131 	for( i = 0; i < 225; i++ )
   132 	{
   133 		PL_ARENA_ALLOCATE( ptr, &ap, 512 );
   134         PR_LOG( tLM, PR_LOG_DEBUG,
   135             ("mr. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", 
   136                 &ap, ap.first.next, ap.current, ap.arenasize, ptr ));
   137 	}
   139     PL_ARENA_RELEASE( &ap, mark1 );
   140     PR_LOG( tLM, PR_LOG_DEBUG,
   141         ("Release-1: %p -- Pool: %p. first: %p, current: %p, size: %d", 
   142                mark1, &ap, ap.first, ap.current, ap.arenasize  ));
   144 	for( i = 0; i < 20; i++ )
   145 	{
   146 		PL_ARENA_ALLOCATE( ptr, &ap, 512 );
   147         PR_LOG( tLM, PR_LOG_DEBUG,
   148             ("mr. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", 
   149                 &ap, ap.first.next, ap.current, ap.arenasize, ptr ));
   150 	}
   152     PL_ARENA_RELEASE( &ap, mark1 );
   153     PR_LOG( tLM, PR_LOG_DEBUG,
   154         ("Release-1. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", 
   155             &ap, ap.first.next, ap.current, ap.arenasize, ptr ));
   157     PL_ARENA_RELEASE( &ap, mark0 );
   158     PR_LOG( tLM, PR_LOG_DEBUG,
   159         ("Release-0. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", 
   160             &ap, ap.first.next, ap.current, ap.arenasize, ptr ));
   162     PL_FreeArenaPool( &ap );
   163     PR_LOG( tLM, PR_LOG_DEBUG,
   164         ("Free. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", 
   165             &ap, ap.first.next, ap.current, ap.arenasize, ptr ));
   167     PL_FinishArenaPool( &ap );
   168     PR_LOG( tLM, PR_LOG_DEBUG,
   169         ("Finish. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", 
   170             &ap, ap.first.next, ap.current, ap.arenasize, ptr ));
   172     return;
   173 } /* end MarkAndRelease() */
   175 /*
   176 ** RandSize() returns a random number in the range 
   177 ** min..max, rounded to the next doubleword
   178 **
   179 */
   180 static PRIntn RandSize( PRIntn min, PRIntn max )
   181 {
   182     PRIntn  sz = (rand() % (max -min)) + min + sizeof(double);
   184     sz &= ~sizeof(double)-1;
   186     return(sz);
   187 }
   190 /*
   191 ** StressThread()
   192 ** A bunch of these beat on individual arenas
   193 ** This tests the free_list protection.
   194 **
   195 */
   196 static void PR_CALLBACK StressThread( void *arg )
   197 {
   198     PLArenaPool ap;
   199     PRIntn i;
   200     PRIntn sz;
   201     void *ptr;
   202     PRThread *tp = PR_GetCurrentThread();
   204     PR_LOG( tLM, PR_LOG_DEBUG, ("Stress Thread %p started\n", PR_GetCurrentThread()));
   205     PL_InitArenaPool( &ap, "TheArena", RandSize( poolMin, poolMax), sizeof(double));
   207     for ( i = 0; i < stressIterations; i++ )
   208     {
   209         PRIntn allocated = 0;
   211         while ( allocated < maxAlloc )
   212         {
   213             sz = RandSize( arenaMin, arenaMax );
   214             PL_ARENA_ALLOCATE( ptr, &ap, sz );
   215             if ( ptr == NULL )
   216             {
   217                 PR_LOG( tLM, PR_LOG_ERROR, ("ARENA_ALLOCATE() returned NULL\n\tAllocated: %d\n", allocated));
   218                 break;
   219             }
   220             allocated += sz;
   221         }
   222         PR_LOG( tLM, PR_LOG_DEBUG, ("Stress thread %p finished one iteration\n", tp));
   223         PL_FreeArenaPool( &ap );
   224     }
   225     PR_LOG( tLM, PR_LOG_DEBUG, ("Stress thread %p finished all iteration\n", tp));
   226     PL_FinishArenaPool( &ap );
   227     PR_LOG( tLM, PR_LOG_DEBUG, ("Stress thread %p after FinishArenaPool()\n", tp));
   229     /* That's all folks! let's quit */
   230     PR_EnterMonitor(tMon);
   231     threadCount--;
   232     PR_Notify(tMon);
   233     PR_ExitMonitor(tMon);    
   234     return;
   235 }    
   237 /*
   238 ** Stress()
   239 ** Flog the hell out of arenas multi-threaded.
   240 ** Do NOT pass an individual arena to another thread.
   241 ** 
   242 */
   243 static void Stress( void )
   244 {
   245     PRThread    *tt;
   246     PRIntn      i;
   248     tMon = PR_NewMonitor();
   250     for ( i = 0 ; i < stressThreads ; i++ )
   251     {
   252         PR_EnterMonitor(tMon);
   253         tt = PR_CreateThread(PR_USER_THREAD,
   254                StressThread,
   255                NULL,
   256                PR_PRIORITY_NORMAL,
   257                PR_GLOBAL_THREAD,
   258                PR_UNJOINABLE_THREAD,
   259                0);
   260         threadCount++;
   261         PR_ExitMonitor(tMon);
   262     }
   264     /* Wait for all threads to exit */
   265     PR_EnterMonitor(tMon);
   266     while ( threadCount != 0 ) 
   267     {
   268         PR_Wait(tMon, PR_INTERVAL_NO_TIMEOUT);
   269     }
   270     PR_ExitMonitor(tMon);
   271 	PR_DestroyMonitor(tMon);
   273     return;
   274 } /* end Stress() */
   276 /*
   277 ** EvaluateResults()
   278 ** uses failed_already to display results and set program
   279 ** exit code.
   280 */
   281 static PRIntn  EvaluateResults(void)
   282 {
   283     PRIntn rc = 0;
   285     if ( failed_already == PR_TRUE )
   286     {
   287         PR_LOG( tLM, PR_LOG_DEBUG, ("FAIL\n"));
   288         rc =1;
   289     } 
   290     else
   291     {
   292         PR_LOG( tLM, PR_LOG_DEBUG, ("PASS\n"));
   293     }
   294     return(rc);
   295 } /* EvaluateResults() */
   297 void Help( void )
   298 {
   299     printf("arena [options]\n");
   300     printf("where options are:\n");
   301     printf("-p <n>   minimum size of an arena pool. Default(%d)\n", poolMin);
   302     printf("-P <n>   maximum size of an arena pool. Default(%d)\n", poolMax);
   303     printf("-a <n>   minimum size of an arena allocation. Default(%d)\n", arenaMin);
   304     printf("-A <n>   maximum size of an arena allocation. Default(%d)\n", arenaMax);
   305     printf("-i <n>   number of iterations in a stress thread. Default(%d)\n", stressIterations);
   306     printf("-s <n>   maximum allocation for a single stress thread. Default(%d)\n", maxAlloc);
   307     printf("-t <n>   number of stress threads. Default(%d)\n", stressThreads );
   308     printf("-d       enable debug mode\n");
   309     printf("\n");
   310     exit(1);
   311 }    
   313 PRIntn main(PRIntn argc, char *argv[])
   314 {
   315     PLOptStatus os;
   316 	PLOptState *opt = PL_CreateOptState(argc, argv, "dhp:P:a:A:i:s:t:");
   317 	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
   318     {
   319 		if (PL_OPT_BAD == os) continue;
   320         switch (opt->option)
   321         {
   322         case 'a':  /* arena Min size */
   323             arenaMin = atol( opt->value );
   324             break;
   325         case 'A':  /* arena Max size  */
   326             arenaMax = atol( opt->value );
   327             break;
   328         case 'p':  /* pool Min size */
   329             poolMin = atol( opt->value );
   330             break;
   331         case 'P':  /* pool Max size */
   332             poolMax = atol( opt->value );
   333             break;
   334         case 'i':  /* Iterations in stress tests */
   335             stressIterations = atol( opt->value );
   336             break;
   337         case 's':  /* storage to get per iteration */
   338             maxAlloc = atol( opt->value );
   339             break;
   340         case 't':  /* Number of stress threads to create */
   341             stressThreads = atol( opt->value );
   342             break;
   343         case 'd':  /* debug mode */
   344 			debug_mode = 1;
   345             break;
   346         case 'h':  /* help */
   347         default:
   348             Help();
   349         } /* end switch() */
   350     } /* end while() */
   351 	PL_DestroyOptState(opt);
   353     srand( (unsigned)time( NULL ) ); /* seed random number generator */
   354     tLM = PR_NewLogModule("testcase");
   357 #if 0
   358 	ArenaAllocate();
   359 	ArenaGrow();
   360 #endif
   362     MarkAndRelease();
   364     Stress();
   366     return(EvaluateResults());
   367 } /* end main() */
   369 /* arena.c */

mercurial