⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 instrumt.c

📁 Netscape NSPR库源码
💻 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:    instrumt.c** Description: This test is for the NSPR debug aids defined in** prcountr.h, prtrace.h, prolock.h**** The test case tests the three debug aids in NSPR:**** Diagnostic messages can be enabled using "instrumt -v 6"** This sets the msgLevel to something that PR_LOG() likes.** Also define in the environment "NSPR_LOG_MODULES=Test:6"**** CounterTest() tests the counter facility. This test** creates 4 threads. Each thread either increments, decrements,** adds to or subtracts from a counter, depending on an argument** passed to the thread at thread-create time. Each of these threads** does COUNT_LIMIT iterations doing its thing. When all 4 threads** are done, the result of the counter is evaluated. If all was atomic,** the the value of the counter should be zero.**** TraceTest():** This test mingles with the counter test. Counters trace.** A thread to extract trace entries on the fly is started.** A thread to dump trace entries to a file is started.**** OrderedLockTest():***********/#include <stdio.h>#include <plstr.h>#include <prclist.h>#include <prmem.h>#include <plgetopt.h> #include <prlog.h> #include <prmon.h> #include <pratom.h> #include <prtrace.h> #include <prcountr.h> #include <prolock.h> #define COUNT_LIMIT  (10 * ( 1024))#define SMALL_TRACE_BUFSIZE  ( 60 * 1024 )typedef enum {    CountLoop = 1,    TraceLoop = 2,    TraceFlow = 3} TraceTypes;PRLogModuleLevel msgLevel = PR_LOG_ALWAYS;PRBool  help = PR_FALSE;PRBool  failed = PR_FALSE;PRLogModuleInfo *lm;PRMonitor   *mon;PRInt32     activeThreads = 0;PR_DEFINE_COUNTER( hCounter );PR_DEFINE_TRACE( hTrace );static void Help(void){    printf("Help? ... Ha!\n");}    static void ListCounters(void){    PR_DEFINE_COUNTER( qh );    PR_DEFINE_COUNTER( rh );    const char *qn, *rn, *dn;    const char **qname = &qn, **rname = &rn, **desc = &dn;    PRUint32    tCtr;    PR_INIT_COUNTER_HANDLE( qh, NULL );    PR_FIND_NEXT_COUNTER_QNAME(qh, qh );    while ( qh != NULL )    {        PR_INIT_COUNTER_HANDLE( rh, NULL );        PR_FIND_NEXT_COUNTER_RNAME(rh, rh, qh );        while ( rh != NULL )        {            PR_GET_COUNTER_NAME_FROM_HANDLE( rh, qname, rname, desc );            tCtr = PR_GET_COUNTER(tCtr, rh);            PR_LOG( lm, msgLevel,                ( "QName: %s  RName: %s  Desc: %s  Value: %ld\n",                 qn, rn, dn, tCtr ));            PR_FIND_NEXT_COUNTER_RNAME(rh, rh, qh );        }         PR_FIND_NEXT_COUNTER_QNAME(qh, qh);    }    return;    } /* end ListCounters() */static void ListTraces(void){    PR_DEFINE_TRACE( qh );    PR_DEFINE_TRACE( rh );    const char *qn, *rn, *dn;    const char **qname = &qn, **rname = &rn, **desc = &dn;    PR_INIT_TRACE_HANDLE( qh, NULL );    PR_FIND_NEXT_TRACE_QNAME(qh, qh );    while ( qh != NULL )    {        PR_INIT_TRACE_HANDLE( rh, NULL );        PR_FIND_NEXT_TRACE_RNAME(rh, rh, qh );        while ( rh != NULL )        {            PR_GET_TRACE_NAME_FROM_HANDLE( rh, qname, rname, desc );            PR_LOG( lm, msgLevel,                ( "QName: %s  RName: %s  Desc: %s",                 qn, rn, dn ));            PR_FIND_NEXT_TRACE_RNAME(rh, rh, qh );        }         PR_FIND_NEXT_TRACE_QNAME(qh, qh);    }    return;    } /* end ListCounters() */static PRInt32 one = 1;static PRInt32 two = 2;static PRInt32 three = 3;static PRInt32 four = 4;/*** Thread to iteratively count something.*/static void PR_CALLBACK CountSomething( void *arg ){    PRInt32 switchVar = *((PRInt32 *)arg);    PRInt32 i;    PR_LOG( lm, msgLevel,        ("CountSomething: begin thread %ld", switchVar ));        for ( i = 0; i < COUNT_LIMIT ; i++)    {        switch ( switchVar )        {        case 1 :            PR_INCREMENT_COUNTER( hCounter );            break;        case 2 :            PR_DECREMENT_COUNTER( hCounter );            break;        case 3 :            PR_ADD_TO_COUNTER( hCounter, 1 );            break;        case 4 :            PR_SUBTRACT_FROM_COUNTER( hCounter, 1 );            break;        default :            PR_ASSERT( 0 );            break;        }        PR_TRACE( hTrace, CountLoop, switchVar, i, 0, 0, 0, 0, 0 );    } /* end for() */    PR_LOG( lm, msgLevel,        ("CounterSomething: end thread %ld", switchVar ));        PR_EnterMonitor(mon);    --activeThreads;    PR_Notify( mon );    PR_ExitMonitor(mon);    return;    } /* end CountSomething() *//*** Create the counter threads.*/static void CounterTest( void ){    PRThread *t1, *t2, *t3, *t4;    PRIntn i = 0;    PR_DEFINE_COUNTER( tc );    PR_DEFINE_COUNTER( zCounter );    PR_LOG( lm, msgLevel,        ("Begin CounterTest"));        /*    ** Test Get and Set of a counter.    **    */    PR_CREATE_COUNTER( zCounter, "Atomic", "get/set test", "test get and set of counter" );    PR_SET_COUNTER( zCounter, 9 );    PR_GET_COUNTER( i, zCounter );    if ( i != 9 )    {        failed = PR_TRUE;        PR_LOG( lm, msgLevel,            ("Counter set/get failed"));    }    activeThreads += 4;    PR_CREATE_COUNTER( hCounter, "Atomic", "SMP Tests", "test atomic nature of counter" );    PR_GET_COUNTER_HANDLE_FROM_NAME( tc, "Atomic", "SMP Tests" );    PR_ASSERT( tc == hCounter );	t1 = PR_CreateThread(PR_USER_THREAD,	        CountSomething, &one, 			PR_PRIORITY_NORMAL,			PR_GLOBAL_THREAD,    		PR_UNJOINABLE_THREAD,			0);	PR_ASSERT(t1);	t2 = PR_CreateThread(PR_USER_THREAD,			CountSomething, &two, 			PR_PRIORITY_NORMAL,			PR_GLOBAL_THREAD,    		PR_UNJOINABLE_THREAD,			0);	PR_ASSERT(t2);        	t3 = PR_CreateThread(PR_USER_THREAD,			CountSomething, &three, 			PR_PRIORITY_NORMAL,			PR_GLOBAL_THREAD,    		PR_UNJOINABLE_THREAD,			0);	PR_ASSERT(t3);        	t4 = PR_CreateThread(PR_USER_THREAD,			CountSomething, &four, 			PR_PRIORITY_NORMAL,			PR_GLOBAL_THREAD,    		PR_UNJOINABLE_THREAD,			0);	PR_ASSERT(t4);    PR_LOG( lm, msgLevel,        ("Counter Threads started"));    ListCounters();    return;} /* end CounterTest() *//*** Thread to dump trace buffer to a file.*/static void PR_CALLBACK RecordTrace(void *arg ){    PR_RECORD_TRACE_ENTRIES();    PR_EnterMonitor(mon);    --activeThreads;    PR_Notify( mon );    PR_ExitMonitor(mon);    return;    } /* end RecordTrace() */#define NUM_TRACE_RECORDS ( 10000 )/*** Thread to extract and print trace entries from the buffer.*/static void PR_CALLBACK SampleTrace( void *arg ){#if defined(DEBUG) || defined(FORCE_NSPR_TRACE)    PRInt32 found, rc;    PRTraceEntry    *foundEntries;    PRInt32 i;        foundEntries = (PRTraceEntry *)PR_Malloc( NUM_TRACE_RECORDS * sizeof(PRTraceEntry));    PR_ASSERT(foundEntries != NULL );    do    {        rc = PR_GetTraceEntries( foundEntries, NUM_TRACE_RECORDS, &found);        PR_LOG( lm, msgLevel,            ("SampleTrace: Lost Data: %ld found: %ld", rc, found ));        if ( found != 0)        {            for ( i = 0 ; i < found; i++ )            {                PR_LOG( lm, msgLevel,                    ("SampleTrace, detail: Thread: %p, Time: %llX, UD0: %ld, UD1: %ld, UD2: %8.8ld",                        (foundEntries +i)->thread,                        (foundEntries +i)->time,                        (foundEntries +i)->userData[0],                         (foundEntries +i)->userData[1],                         (foundEntries +i)->userData[2] ));             }        }        PR_Sleep(PR_MillisecondsToInterval(50));    }    while( found != 0 && activeThreads >= 1 );    PR_Free( foundEntries );    PR_EnterMonitor(mon);    --activeThreads;    PR_Notify( mon );    PR_ExitMonitor(mon);    PR_LOG( lm, msgLevel,        ("SampleTrace(): exiting"));#endif    return;    } /* end RecordTrace() *//*** Basic trace test.*/static void TraceTest( void ){    PRInt32 i;    PRInt32 size;    PR_DEFINE_TRACE( th );    PRThread *t1, *t2;        PR_LOG( lm, msgLevel,        ("Begin TraceTest"));        size = SMALL_TRACE_BUFSIZE;    PR_SET_TRACE_OPTION( PRTraceBufSize, &size );    PR_GET_TRACE_OPTION( PRTraceBufSize, &i );        PR_CREATE_TRACE( th, "TraceTest", "tt2", "A description for the trace test" );    PR_CREATE_TRACE( th, "TraceTest", "tt3", "A description for the trace test" );    PR_CREATE_TRACE( th, "TraceTest", "tt4", "A description for the trace test" );    PR_CREATE_TRACE( th, "TraceTest", "tt5", "A description for the trace test" );    PR_CREATE_TRACE( th, "TraceTest", "tt6", "A description for the trace test" );    PR_CREATE_TRACE( th, "TraceTest", "tt7", "A description for the trace test" );    PR_CREATE_TRACE( th, "TraceTest", "tt8", "A description for the trace test" );    PR_CREATE_TRACE( th, "Trace Test", "tt0", "QName is Trace Test, not TraceTest" );    PR_CREATE_TRACE( th, "Trace Test", "tt1", "QName is Trace Test, not TraceTest" );    PR_CREATE_TRACE( th, "Trace Test", "tt2", "QName is Trace Test, not TraceTest" );    PR_CREATE_TRACE( th, "Trace Test", "tt3", "QName is Trace Test, not TraceTest" );    PR_CREATE_TRACE( th, "Trace Test", "tt4", "QName is Trace Test, not TraceTest" );    PR_CREATE_TRACE( th, "Trace Test", "tt5", "QName is Trace Test, not TraceTest" );    PR_CREATE_TRACE( th, "Trace Test", "tt6", "QName is Trace Test, not TraceTest" );    PR_CREATE_TRACE( th, "Trace Test", "tt7", "QName is Trace Test, not TraceTest" );    PR_CREATE_TRACE( th, "Trace Test", "tt8", "QName is Trace Test, not TraceTest" );    PR_CREATE_TRACE( th, "Trace Test", "tt9", "QName is Trace Test, not TraceTest" );    PR_CREATE_TRACE( th, "Trace Test", "tt10", "QName is Trace Test, not TraceTest" );    activeThreads += 2;	t1 = PR_CreateThread(PR_USER_THREAD,			RecordTrace, NULL, 			PR_PRIORITY_NORMAL,			PR_GLOBAL_THREAD,    		PR_UNJOINABLE_THREAD,			0);	PR_ASSERT(t1);	t2 = PR_CreateThread(PR_USER_THREAD,			SampleTrace, 0, 			PR_PRIORITY_NORMAL,			PR_GLOBAL_THREAD,    		PR_UNJOINABLE_THREAD,			0);	PR_ASSERT(t2);            ListTraces();    PR_GET_TRACE_HANDLE_FROM_NAME( th, "TraceTest","tt1" );    PR_ASSERT( th == hTrace );    PR_LOG( lm, msgLevel,        ("End TraceTest"));        return;} /* end TraceTest() *//*** Ordered lock test.*/static void OrderedLockTest( void ){    PR_LOG( lm, msgLevel,        ("Begin OrderedLockTest"));        } /* end OrderedLockTest() */PRIntn main(PRIntn argc, char *argv[]){#if defined(DEBUG) || defined(FORCE_NSPR_TRACE)    PRUint32    counter;    PLOptStatus os;    PLOptState *opt = PL_CreateOptState(argc, argv, "hdv:");    lm = PR_NewLogModule("Test");	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))    {		if (PL_OPT_BAD == os) continue;        switch (opt->option)        {        case 'v':  /* verbose mode */			msgLevel = (PRLogModuleLevel)atol( opt->value);            break;        case 'h':  /* help message */			Help();			help = PR_TRUE;            break;         default:            break;        }    }	PL_DestroyOptState(opt);    PR_CREATE_TRACE( hTrace, "TraceTest", "tt1", "A description for the trace test" );    mon = PR_NewMonitor();    PR_EnterMonitor( mon );    TraceTest();    CounterTest();    OrderedLockTest();    /* Wait for all threads to exit */    while ( activeThreads > 0 ) {        if ( activeThreads == 1 )            PR_SET_TRACE_OPTION( PRTraceStopRecording, NULL );    	PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);        PR_GET_COUNTER( counter, hCounter );    }    PR_ExitMonitor( mon );    /*    ** Evaluate results    */    PR_GET_COUNTER( counter, hCounter );    if ( counter != 0 )    {        failed = PR_TRUE;        PR_LOG( lm, msgLevel,            ("Expected counter == 0, found: %ld", counter));        printf("FAIL\n");    }    else    {        printf("PASS\n");    }    PR_DESTROY_COUNTER( hCounter );    PR_DestroyMonitor( mon );    PR_TRACE( hTrace, TraceFlow, 0xfff,0,0,0,0,0,0);    PR_DESTROY_TRACE( hTrace );#else    printf("Test not defined\n");#endif    return 0;}  /* main() *//* end instrumt.c */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -