📄 arena.c
字号:
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Netscape Portable Runtime (NSPR). * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998-2000 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. *//*** File: arena.c** Description: Testing arenas***/#include <string.h>#include <time.h>#include <stdlib.h>#include "nspr.h"#include "plarena.h"#include "plgetopt.h"PRLogModuleInfo *tLM;PRIntn threadCount = 0;PRMonitor *tMon;PRBool failed_already = PR_FALSE;/* Arguments from the command line with default values */PRIntn debug_mode = 0;PRIntn poolMin = 4096;PRIntn poolMax = (100 * 4096);PRIntn arenaMin = 40;PRIntn arenaMax = (100 * 40);PRIntn stressIterations = 15;PRIntn maxAlloc = (1024 * 1024);PRIntn stressThreads = 4;void DumpAll( void ){ return;}/*** Test Arena allocation.*/static void ArenaAllocate( void ){ PLArenaPool ap; void *ptr; PRInt32 i; PL_InitArenaPool( &ap, "AllocArena", 2048, sizeof(double)); PR_LOG( tLM, PR_LOG_DEBUG, ("AA, InitPool -- Pool: %p. first: %p, current: %p, size: %d", &ap, ap.first, ap.current, ap.arenasize )); for( i = 0; i < 150; i++ ) { PL_ARENA_ALLOCATE( ptr, &ap, 512 ); PR_LOG( tLM, PR_LOG_DEBUG,("AA, after alloc -- Pool: %p. first: %p, current: %p, size: %d", &ap, ap.first, ap.current, ap.arenasize )); PR_LOG( tLM, PR_LOG_DEBUG,( "AA -- Pool: %p. alloc: %p ", &ap, ptr )); } PL_FreeArenaPool( &ap ); for( i = 0; i < 221; i++ ) { PL_ARENA_ALLOCATE( ptr, &ap, 512 ); PR_LOG( tLM, PR_LOG_DEBUG,("AA, after alloc -- Pool: %p. first: %p, current: %p, size: %d", &ap, ap.first, ap.current, ap.arenasize )); PR_LOG( tLM, PR_LOG_DEBUG,( "AA -- Pool: %p. alloc: %p ", &ap, ptr )); } PL_FreeArenaPool( &ap ); return;} /* end ArenaGrow() *//*** Test Arena grow.*/static void ArenaGrow( void ){ PLArenaPool ap; void *ptr; PRInt32 i; PL_InitArenaPool( &ap, "TheArena", 4096, sizeof(double)); PL_ARENA_ALLOCATE( ptr, &ap, 512 ); PR_LOG( tLM, PR_LOG_DEBUG, ("Before growth -- Pool: %p. alloc: %p ", &ap, ptr )); for( i = 0; i < 10; i++ ) { PL_ARENA_GROW( ptr, &ap, 512, 7000 ); PR_LOG( tLM, PR_LOG_DEBUG, ("After growth -- Pool: %p. alloc: %p ", &ap, ptr )); } return;} /* end ArenaGrow() *//*** Test arena Mark and Release.*/static void MarkAndRelease( void ){ PLArenaPool ap; void *ptr = NULL; void *mark0, *mark1; PRIntn i; PL_InitArenaPool( &ap, "TheArena", 4096, sizeof(double)); mark0 = PL_ARENA_MARK( &ap ); PR_LOG( tLM, PR_LOG_DEBUG, ("mark0. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p, m0: %p", &ap, ap.first.next, ap.current, ap.arenasize, ptr, mark0 )); for( i = 0; i < 201; i++ ) { PL_ARENA_ALLOCATE( ptr, &ap, 512 ); PR_LOG( tLM, PR_LOG_DEBUG, ("mr. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", &ap, ap.first.next, ap.current, ap.arenasize, ptr )); } mark1 = PL_ARENA_MARK( &ap ); PR_LOG( tLM, PR_LOG_DEBUG, ("mark1. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p, m1: %p", &ap, ap.first.next, ap.current, ap.arenasize, ptr, mark1 )); for( i = 0; i < 225; i++ ) { PL_ARENA_ALLOCATE( ptr, &ap, 512 ); PR_LOG( tLM, PR_LOG_DEBUG, ("mr. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", &ap, ap.first.next, ap.current, ap.arenasize, ptr )); } PL_ARENA_RELEASE( &ap, mark1 ); PR_LOG( tLM, PR_LOG_DEBUG, ("Release-1: %p -- Pool: %p. first: %p, current: %p, size: %d", mark1, &ap, ap.first, ap.current, ap.arenasize )); for( i = 0; i < 20; i++ ) { PL_ARENA_ALLOCATE( ptr, &ap, 512 ); PR_LOG( tLM, PR_LOG_DEBUG, ("mr. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", &ap, ap.first.next, ap.current, ap.arenasize, ptr )); } PL_ARENA_RELEASE( &ap, mark1 ); PR_LOG( tLM, PR_LOG_DEBUG, ("Release-1. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", &ap, ap.first.next, ap.current, ap.arenasize, ptr )); PL_ARENA_RELEASE( &ap, mark0 ); PR_LOG( tLM, PR_LOG_DEBUG, ("Release-0. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", &ap, ap.first.next, ap.current, ap.arenasize, ptr )); PL_FreeArenaPool( &ap ); PR_LOG( tLM, PR_LOG_DEBUG, ("Free. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", &ap, ap.first.next, ap.current, ap.arenasize, ptr )); PL_FinishArenaPool( &ap ); PR_LOG( tLM, PR_LOG_DEBUG, ("Finish. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", &ap, ap.first.next, ap.current, ap.arenasize, ptr )); return;} /* end MarkAndRelease() *//*** RandSize() returns a random number in the range ** min..max, rounded to the next doubleword***/static PRIntn RandSize( PRIntn min, PRIntn max ){ PRIntn sz = (rand() % (max -min)) + min + sizeof(double); sz &= ~sizeof(double)-1; return(sz);}/*** StressThread()** A bunch of these beat on individual arenas** This tests the free_list protection.***/static void PR_CALLBACK StressThread( void *arg ){ PLArenaPool ap; PRIntn i; PRIntn sz; void *ptr; PRThread *tp = PR_GetCurrentThread(); PR_LOG( tLM, PR_LOG_DEBUG, ("Stress Thread %p started\n", PR_GetCurrentThread())); PL_InitArenaPool( &ap, "TheArena", RandSize( poolMin, poolMax), sizeof(double)); for ( i = 0; i < stressIterations; i++ ) { PRIntn allocated = 0; while ( allocated < maxAlloc ) { sz = RandSize( arenaMin, arenaMax ); PL_ARENA_ALLOCATE( ptr, &ap, sz ); if ( ptr == NULL ) { PR_LOG( tLM, PR_LOG_ERROR, ("ARENA_ALLOCATE() returned NULL\n\tAllocated: %d\n", allocated)); break; } allocated += sz; } PR_LOG( tLM, PR_LOG_DEBUG, ("Stress thread %p finished one iteration\n", tp)); PL_FreeArenaPool( &ap ); } PR_LOG( tLM, PR_LOG_DEBUG, ("Stress thread %p finished all iteration\n", tp)); PL_FinishArenaPool( &ap ); PR_LOG( tLM, PR_LOG_DEBUG, ("Stress thread %p after FinishArenaPool()\n", tp)); /* That's all folks! let's quit */ PR_EnterMonitor(tMon); threadCount--; PR_Notify(tMon); PR_ExitMonitor(tMon); return;} /*** Stress()** Flog the hell out of arenas multi-threaded.** Do NOT pass an individual arena to another thread.** */static void Stress( void ){ PRThread *tt; PRIntn i; tMon = PR_NewMonitor(); for ( i = 0 ; i < stressThreads ; i++ ) { PR_EnterMonitor(tMon); tt = PR_CreateThread(PR_USER_THREAD, StressThread, NULL, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0); threadCount++; PR_ExitMonitor(tMon); } /* Wait for all threads to exit */ PR_EnterMonitor(tMon); while ( threadCount != 0 ) { PR_Wait(tMon, PR_INTERVAL_NO_TIMEOUT); } PR_ExitMonitor(tMon); PR_DestroyMonitor(tMon); return;} /* end Stress() *//*** EvaluateResults()** uses failed_already to display results and set program** exit code.*/static PRIntn EvaluateResults(void){ PRIntn rc = 0; if ( failed_already == PR_TRUE ) { PR_LOG( tLM, PR_LOG_DEBUG, ("FAIL\n")); rc =1; } else { PR_LOG( tLM, PR_LOG_DEBUG, ("PASS\n")); } return(rc);} /* EvaluateResults() */void Help( void ){ printf("arena [options]\n"); printf("where options are:\n"); printf("-p <n> minimum size of an arena pool. Default(%d)\n", poolMin); printf("-P <n> maximum size of an arena pool. Default(%d)\n", poolMax); printf("-a <n> minimum size of an arena allocation. Default(%d)\n", arenaMin); printf("-A <n> maximum size of an arena allocation. Default(%d)\n", arenaMax); printf("-i <n> number of iterations in a stress thread. Default(%d)\n", stressIterations); printf("-s <n> maximum allocation for a single stress thread. Default(%d)\n", maxAlloc); printf("-t <n> number of stress threads. Default(%d)\n", stressThreads ); printf("-d enable debug mode\n"); printf("\n"); exit(1);} PRIntn main(PRIntn argc, char *argv[]){ PLOptStatus os; PLOptState *opt = PL_CreateOptState(argc, argv, "dhp:P:a:A:i:s:t:"); while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { if (PL_OPT_BAD == os) continue; switch (opt->option) { case 'a': /* arena Min size */ arenaMin = atol( opt->value ); break; case 'A': /* arena Max size */ arenaMax = atol( opt->value ); break; case 'p': /* pool Min size */ poolMin = atol( opt->value ); break; case 'P': /* pool Max size */ poolMax = atol( opt->value ); break; case 'i': /* Iterations in stress tests */ stressIterations = atol( opt->value ); break; case 's': /* storage to get per iteration */ maxAlloc = atol( opt->value ); break; case 't': /* Number of stress threads to create */ stressThreads = atol( opt->value ); break; case 'd': /* debug mode */ debug_mode = 1; break; case 'h': /* help */ default: Help(); } /* end switch() */ } /* end while() */ PL_DestroyOptState(opt); srand( (unsigned)time( NULL ) ); /* seed random number generator */ tLM = PR_NewLogModule("testcase");#if 0 ArenaAllocate(); ArenaGrow();#endif MarkAndRelease(); Stress(); return(EvaluateResults());} /* end main() *//* arena.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -