Bug 1837620 - Part 1: Remove baseline ICs that guard shapes when the shape becomes...
[gecko.git] / nsprpub / lib / tests / arena.c
blob2be2d5b4c1cf01335571bb3fb74f0eb01148c1f3
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 **
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 )
36 return;
40 ** Test Arena allocation.
42 static void ArenaAllocate( void )
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++ )
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 ));
61 PL_FreeArenaPool( &ap );
63 for( i = 0; i < 221; i++ )
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 ));
72 PL_FreeArenaPool( &ap );
74 return;
75 } /* end ArenaGrow() */
77 ** Test Arena grow.
79 static void ArenaGrow( void )
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++ )
92 PL_ARENA_GROW( ptr, &ap, 512, 7000 );
93 PR_LOG( tLM, PR_LOG_DEBUG, ("After growth -- Pool: %p. alloc: %p ", &ap, ptr ));
97 return;
98 } /* end ArenaGrow() */
102 ** Test arena Mark and Release.
104 static void MarkAndRelease( void )
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++ )
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 ));
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++ )
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 ));
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++ )
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 ));
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() */
176 ** RandSize() returns a random number in the range
177 ** min..max, rounded to the next doubleword
180 static PRIntn RandSize( PRIntn min, PRIntn max )
182 PRIntn sz = (rand() % (max -min)) + min + sizeof(double);
184 sz &= ~sizeof(double)-1;
186 return(sz);
191 ** StressThread()
192 ** A bunch of these beat on individual arenas
193 ** This tests the free_list protection.
196 static void PR_CALLBACK StressThread( void *arg )
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++ )
209 PRIntn allocated = 0;
211 while ( allocated < maxAlloc )
213 sz = RandSize( arenaMin, arenaMax );
214 PL_ARENA_ALLOCATE( ptr, &ap, sz );
215 if ( ptr == NULL )
217 PR_LOG( tLM, PR_LOG_ERROR, ("ARENA_ALLOCATE() returned NULL\n\tAllocated: %d\n", allocated));
218 break;
220 allocated += sz;
222 PR_LOG( tLM, PR_LOG_DEBUG, ("Stress thread %p finished one iteration\n", tp));
223 PL_FreeArenaPool( &ap );
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;
238 ** Stress()
239 ** Flog the hell out of arenas multi-threaded.
240 ** Do NOT pass an individual arena to another thread.
243 static void Stress( void )
245 PRThread *tt;
246 PRIntn i;
248 tMon = PR_NewMonitor();
250 for ( i = 0 ; i < stressThreads ; i++ )
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,
260 threadCount++;
261 PR_ExitMonitor(tMon);
264 /* Wait for all threads to exit */
265 PR_EnterMonitor(tMon);
266 while ( threadCount != 0 )
268 PR_Wait(tMon, PR_INTERVAL_NO_TIMEOUT);
270 PR_ExitMonitor(tMon);
271 PR_DestroyMonitor(tMon);
273 return;
274 } /* end Stress() */
277 ** EvaluateResults()
278 ** uses failed_already to display results and set program
279 ** exit code.
281 static PRIntn EvaluateResults(void)
283 PRIntn rc = 0;
285 if ( failed_already == PR_TRUE )
287 PR_LOG( tLM, PR_LOG_DEBUG, ("FAIL\n"));
288 rc =1;
290 else
292 PR_LOG( tLM, PR_LOG_DEBUG, ("PASS\n"));
294 return(rc);
295 } /* EvaluateResults() */
297 void Help( void )
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);
313 PRIntn main(PRIntn argc, char *argv[])
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)))
319 if (PL_OPT_BAD == os) {
320 continue;
322 switch (opt->option)
324 case 'a': /* arena Min size */
325 arenaMin = atol( opt->value );
326 break;
327 case 'A': /* arena Max size */
328 arenaMax = atol( opt->value );
329 break;
330 case 'p': /* pool Min size */
331 poolMin = atol( opt->value );
332 break;
333 case 'P': /* pool Max size */
334 poolMax = atol( opt->value );
335 break;
336 case 'i': /* Iterations in stress tests */
337 stressIterations = atol( opt->value );
338 break;
339 case 's': /* storage to get per iteration */
340 maxAlloc = atol( opt->value );
341 break;
342 case 't': /* Number of stress threads to create */
343 stressThreads = atol( opt->value );
344 break;
345 case 'd': /* debug mode */
346 debug_mode = 1;
347 break;
348 case 'h': /* help */
349 default:
350 Help();
351 } /* end switch() */
352 } /* end while() */
353 PL_DestroyOptState(opt);
355 srand( (unsigned)time( NULL ) ); /* seed random number generator */
356 tLM = PR_NewLogModule("testcase");
359 #if 0
360 ArenaAllocate();
361 ArenaGrow();
362 #endif
364 MarkAndRelease();
366 Stress();
368 return(EvaluateResults());
369 } /* end main() */
371 /* arena.c */