nsprpub/pr/tests/instrumt.c

Wed, 31 Dec 2014 07:53:36 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:53:36 +0100
branch
TOR_BUG_3246
changeset 5
4ab42b5ab56c
permissions
-rw-r--r--

Correct small whitespace inconsistency, lost while renaming variables.

     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:    instrumt.c
     8 ** Description: This test is for the NSPR debug aids defined in
     9 ** prcountr.h, prtrace.h, prolock.h
    10 **
    11 ** The test case tests the three debug aids in NSPR:
    12 **
    13 ** Diagnostic messages can be enabled using "instrumt -v 6"
    14 ** This sets the msgLevel to something that PR_LOG() likes.
    15 ** Also define in the environment "NSPR_LOG_MODULES=Test:6"
    16 **
    17 ** CounterTest() tests the counter facility. This test
    18 ** creates 4 threads. Each thread either increments, decrements,
    19 ** adds to or subtracts from a counter, depending on an argument
    20 ** passed to the thread at thread-create time. Each of these threads
    21 ** does COUNT_LIMIT iterations doing its thing. When all 4 threads
    22 ** are done, the result of the counter is evaluated. If all was atomic,
    23 ** the the value of the counter should be zero.
    24 **
    25 ** TraceTest():
    26 ** This test mingles with the counter test. Counters trace.
    27 ** A thread to extract trace entries on the fly is started.
    28 ** A thread to dump trace entries to a file is started.
    29 **
    30 ** OrderedLockTest():
    31 **
    32 **
    33 **
    34 **
    35 **
    36 */
    38 #include <stdio.h>
    39 #include <plstr.h>
    40 #include <prclist.h>
    41 #include <prmem.h>
    42 #include <plgetopt.h> 
    43 #include <prlog.h> 
    44 #include <prmon.h> 
    45 #include <pratom.h> 
    46 #include <prtrace.h> 
    47 #include <prcountr.h> 
    48 #include <prolock.h> 
    50 #define COUNT_LIMIT  (10 * ( 1024))
    52 #define SMALL_TRACE_BUFSIZE  ( 60 * 1024 )
    54 typedef enum 
    55 {
    56     CountLoop = 1,
    57     TraceLoop = 2,
    58     TraceFlow = 3
    59 } TraceTypes;
    62 PRLogModuleLevel msgLevel = PR_LOG_ALWAYS;
    64 PRBool  help = PR_FALSE;
    65 PRBool  failed = PR_FALSE;
    68 PRLogModuleInfo *lm;
    69 PRMonitor   *mon;
    70 PRInt32     activeThreads = 0;
    71 PR_DEFINE_COUNTER( hCounter );
    72 PR_DEFINE_TRACE( hTrace );
    74 static void Help(void)
    75 {
    76     printf("Help? ... Ha!\n");
    77 }    
    79 static void ListCounters(void)
    80 {
    81     PR_DEFINE_COUNTER( qh );
    82     PR_DEFINE_COUNTER( rh );
    83     const char *qn, *rn, *dn;
    84     const char **qname = &qn, **rname = &rn, **desc = &dn;
    85     PRUint32    tCtr;
    87     PR_INIT_COUNTER_HANDLE( qh, NULL );
    88     PR_FIND_NEXT_COUNTER_QNAME(qh, qh );
    89     while ( qh != NULL )
    90     {
    91         PR_INIT_COUNTER_HANDLE( rh, NULL );
    92         PR_FIND_NEXT_COUNTER_RNAME(rh, rh, qh );
    93         while ( rh != NULL )
    94         {
    95             PR_GET_COUNTER_NAME_FROM_HANDLE( rh, qname, rname, desc );
    96             PR_GET_COUNTER(tCtr, rh);
    97             PR_LOG( lm, msgLevel,
    98                 ( "QName: %s  RName: %s  Desc: %s  Value: %ld\n", 
    99                 qn, rn, dn, tCtr ));
   100             PR_FIND_NEXT_COUNTER_RNAME(rh, rh, qh );
   101         } 
   102         PR_FIND_NEXT_COUNTER_QNAME(qh, qh);
   103     }
   104     return;    
   105 } /* end ListCounters() */
   107 static void ListTraces(void)
   108 {
   109     PR_DEFINE_TRACE( qh );
   110     PR_DEFINE_TRACE( rh );
   111     const char *qn, *rn, *dn;
   112     const char **qname = &qn, **rname = &rn, **desc = &dn;
   114     PR_INIT_TRACE_HANDLE( qh, NULL );
   115     PR_FIND_NEXT_TRACE_QNAME(qh, qh );
   116     while ( qh != NULL )
   117     {
   118         PR_INIT_TRACE_HANDLE( rh, NULL );
   119         PR_FIND_NEXT_TRACE_RNAME(rh, rh, qh );
   120         while ( rh != NULL )
   121         {
   122             PR_GET_TRACE_NAME_FROM_HANDLE( rh, qname, rname, desc );
   123             PR_LOG( lm, msgLevel,
   124                 ( "QName: %s  RName: %s  Desc: %s", 
   125                 qn, rn, dn ));
   126             PR_FIND_NEXT_TRACE_RNAME(rh, rh, qh );
   127         } 
   128         PR_FIND_NEXT_TRACE_QNAME(qh, qh);
   129     }
   130     return;    
   131 } /* end ListCounters() */
   134 static PRInt32 one = 1;
   135 static PRInt32 two = 2;
   136 static PRInt32 three = 3;
   137 static PRInt32 four = 4;
   139 /*
   140 ** Thread to iteratively count something.
   141 */
   142 static void PR_CALLBACK CountSomething( void *arg )
   143 {
   144     PRInt32 switchVar = *((PRInt32 *)arg);
   145     PRInt32 i;
   147     PR_LOG( lm, msgLevel,
   148         ("CountSomething: begin thread %ld", switchVar ));
   150     for ( i = 0; i < COUNT_LIMIT ; i++)
   151     {
   152         switch ( switchVar )
   153         {
   154         case 1 :
   155             PR_INCREMENT_COUNTER( hCounter );
   156             break;
   157         case 2 :
   158             PR_DECREMENT_COUNTER( hCounter );
   159             break;
   160         case 3 :
   161             PR_ADD_TO_COUNTER( hCounter, 1 );
   162             break;
   163         case 4 :
   164             PR_SUBTRACT_FROM_COUNTER( hCounter, 1 );
   165             break;
   166         default :
   167             PR_ASSERT( 0 );
   168             break;
   169         }
   170         PR_TRACE( hTrace, CountLoop, switchVar, i, 0, 0, 0, 0, 0 );
   171     } /* end for() */
   173     PR_LOG( lm, msgLevel,
   174         ("CounterSomething: end thread %ld", switchVar ));
   176     PR_EnterMonitor(mon);
   177     --activeThreads;
   178     PR_Notify( mon );
   179     PR_ExitMonitor(mon);
   181     return;    
   182 } /* end CountSomething() */
   184 /*
   185 ** Create the counter threads.
   186 */
   187 static void CounterTest( void )
   188 {
   189     PRThread *t1, *t2, *t3, *t4;
   190     PRIntn i = 0;
   191     PR_DEFINE_COUNTER( tc );
   192     PR_DEFINE_COUNTER( zCounter );
   194     PR_LOG( lm, msgLevel,
   195         ("Begin CounterTest"));
   197     /*
   198     ** Test Get and Set of a counter.
   199     **
   200     */
   201     PR_CREATE_COUNTER( zCounter, "Atomic", "get/set test", "test get and set of counter" );
   202     PR_SET_COUNTER( zCounter, 9 );
   203     PR_GET_COUNTER( i, zCounter );
   204     if ( i != 9 )
   205     {
   206         failed = PR_TRUE;
   207         PR_LOG( lm, msgLevel,
   208             ("Counter set/get failed"));
   209     }
   211     activeThreads += 4;
   212     PR_CREATE_COUNTER( hCounter, "Atomic", "SMP Tests", "test atomic nature of counter" );
   214     PR_GET_COUNTER_HANDLE_FROM_NAME( tc, "Atomic", "SMP Tests" );
   215     PR_ASSERT( tc == hCounter );
   217 	t1 = PR_CreateThread(PR_USER_THREAD,
   218 	        CountSomething, &one, 
   219 			PR_PRIORITY_NORMAL,
   220 			PR_GLOBAL_THREAD,
   221     		PR_UNJOINABLE_THREAD,
   222 			0);
   223 	PR_ASSERT(t1);
   225 	t2 = PR_CreateThread(PR_USER_THREAD,
   226 			CountSomething, &two, 
   227 			PR_PRIORITY_NORMAL,
   228 			PR_GLOBAL_THREAD,
   229     		PR_UNJOINABLE_THREAD,
   230 			0);
   231 	PR_ASSERT(t2);
   233 	t3 = PR_CreateThread(PR_USER_THREAD,
   234 			CountSomething, &three, 
   235 			PR_PRIORITY_NORMAL,
   236 			PR_GLOBAL_THREAD,
   237     		PR_UNJOINABLE_THREAD,
   238 			0);
   239 	PR_ASSERT(t3);
   241 	t4 = PR_CreateThread(PR_USER_THREAD,
   242 			CountSomething, &four, 
   243 			PR_PRIORITY_NORMAL,
   244 			PR_GLOBAL_THREAD,
   245     		PR_UNJOINABLE_THREAD,
   246 			0);
   247 	PR_ASSERT(t4);
   249     PR_LOG( lm, msgLevel,
   250         ("Counter Threads started"));
   252     ListCounters();
   253     return;
   254 } /* end CounterTest() */
   256 /*
   257 ** Thread to dump trace buffer to a file.
   258 */
   259 static void PR_CALLBACK RecordTrace(void *arg )
   260 {
   261     PR_RECORD_TRACE_ENTRIES();
   263     PR_EnterMonitor(mon);
   264     --activeThreads;
   265     PR_Notify( mon );
   266     PR_ExitMonitor(mon);
   268     return;    
   269 } /* end RecordTrace() */
   273 #define NUM_TRACE_RECORDS ( 10000 )
   274 /*
   275 ** Thread to extract and print trace entries from the buffer.
   276 */
   277 static void PR_CALLBACK SampleTrace( void *arg )
   278 {
   279 #if defined(DEBUG) || defined(FORCE_NSPR_TRACE)
   280     PRInt32 found, rc;
   281     PRTraceEntry    *foundEntries;
   282     PRInt32 i;
   284     foundEntries = (PRTraceEntry *)PR_Malloc( NUM_TRACE_RECORDS * sizeof(PRTraceEntry));
   285     PR_ASSERT(foundEntries != NULL );
   287     do
   288     {
   289         rc = PR_GetTraceEntries( foundEntries, NUM_TRACE_RECORDS, &found);
   290         PR_LOG( lm, msgLevel,
   291             ("SampleTrace: Lost Data: %ld found: %ld", rc, found ));
   293         if ( found != 0)
   294         {
   295             for ( i = 0 ; i < found; i++ )
   296             {
   297                 PR_LOG( lm, msgLevel,
   298                     ("SampleTrace, detail: Thread: %p, Time: %llX, UD0: %ld, UD1: %ld, UD2: %8.8ld",
   299                         (foundEntries +i)->thread,
   300                         (foundEntries +i)->time,
   301                         (foundEntries +i)->userData[0], 
   302                         (foundEntries +i)->userData[1], 
   303                         (foundEntries +i)->userData[2] )); 
   304             }
   305         }
   306         PR_Sleep(PR_MillisecondsToInterval(50));
   307     }
   308     while( found != 0 && activeThreads >= 1 );
   310     PR_Free( foundEntries );
   312     PR_EnterMonitor(mon);
   313     --activeThreads;
   314     PR_Notify( mon );
   315     PR_ExitMonitor(mon);
   317     PR_LOG( lm, msgLevel,
   318         ("SampleTrace(): exiting"));
   320 #endif
   321     return;    
   322 } /* end RecordTrace() */
   324 /*
   325 ** Basic trace test.
   326 */
   327 static void TraceTest( void )
   328 {
   329     PRInt32 i;
   330     PRInt32 size;
   331     PR_DEFINE_TRACE( th );
   332     PRThread *t1, *t2;
   334     PR_LOG( lm, msgLevel,
   335         ("Begin TraceTest"));    
   337     size = SMALL_TRACE_BUFSIZE;
   338     PR_SET_TRACE_OPTION( PRTraceBufSize, &size );
   339     PR_GET_TRACE_OPTION( PRTraceBufSize, &i );
   341     PR_CREATE_TRACE( th, "TraceTest", "tt2", "A description for the trace test" );
   342     PR_CREATE_TRACE( th, "TraceTest", "tt3", "A description for the trace test" );
   343     PR_CREATE_TRACE( th, "TraceTest", "tt4", "A description for the trace test" );
   344     PR_CREATE_TRACE( th, "TraceTest", "tt5", "A description for the trace test" );
   345     PR_CREATE_TRACE( th, "TraceTest", "tt6", "A description for the trace test" );
   346     PR_CREATE_TRACE( th, "TraceTest", "tt7", "A description for the trace test" );
   347     PR_CREATE_TRACE( th, "TraceTest", "tt8", "A description for the trace test" );
   349     PR_CREATE_TRACE( th, "Trace Test", "tt0", "QName is Trace Test, not TraceTest" );
   350     PR_CREATE_TRACE( th, "Trace Test", "tt1", "QName is Trace Test, not TraceTest" );
   351     PR_CREATE_TRACE( th, "Trace Test", "tt2", "QName is Trace Test, not TraceTest" );
   352     PR_CREATE_TRACE( th, "Trace Test", "tt3", "QName is Trace Test, not TraceTest" );
   353     PR_CREATE_TRACE( th, "Trace Test", "tt4", "QName is Trace Test, not TraceTest" );
   354     PR_CREATE_TRACE( th, "Trace Test", "tt5", "QName is Trace Test, not TraceTest" );
   355     PR_CREATE_TRACE( th, "Trace Test", "tt6", "QName is Trace Test, not TraceTest" );
   356     PR_CREATE_TRACE( th, "Trace Test", "tt7", "QName is Trace Test, not TraceTest" );
   357     PR_CREATE_TRACE( th, "Trace Test", "tt8", "QName is Trace Test, not TraceTest" );
   358     PR_CREATE_TRACE( th, "Trace Test", "tt9", "QName is Trace Test, not TraceTest" );
   359     PR_CREATE_TRACE( th, "Trace Test", "tt10", "QName is Trace Test, not TraceTest" );
   363     activeThreads += 2;
   364 	t1 = PR_CreateThread(PR_USER_THREAD,
   365 			RecordTrace, NULL, 
   366 			PR_PRIORITY_NORMAL,
   367 			PR_GLOBAL_THREAD,
   368     		PR_UNJOINABLE_THREAD,
   369 			0);
   370 	PR_ASSERT(t1);
   372 	t2 = PR_CreateThread(PR_USER_THREAD,
   373 			SampleTrace, 0, 
   374 			PR_PRIORITY_NORMAL,
   375 			PR_GLOBAL_THREAD,
   376     		PR_UNJOINABLE_THREAD,
   377 			0);
   378 	PR_ASSERT(t2);
   380     ListTraces();
   382     PR_GET_TRACE_HANDLE_FROM_NAME( th, "TraceTest","tt1" );
   383     PR_ASSERT( th == hTrace );
   385     PR_LOG( lm, msgLevel,
   386         ("End TraceTest"));    
   387     return;
   388 } /* end TraceTest() */
   391 /*
   392 ** Ordered lock test.
   393 */
   394 static void OrderedLockTest( void )
   395 {
   396     PR_LOG( lm, msgLevel,
   397         ("Begin OrderedLockTest"));    
   400 } /* end OrderedLockTest() */
   403 int main(int argc, char **argv)
   404 {
   405 #if defined(DEBUG) || defined(FORCE_NSPR_TRACE)
   406     PRUint32    counter;
   407     PLOptStatus os;
   408     PLOptState *opt = PL_CreateOptState(argc, argv, "hdv:");
   409     lm = PR_NewLogModule("Test");
   411 	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
   412     {
   413 		if (PL_OPT_BAD == os) continue;
   414         switch (opt->option)
   415         {
   416         case 'v':  /* verbose mode */
   417 			msgLevel = (PRLogModuleLevel)atol( opt->value);
   418             break;
   419         case 'h':  /* help message */
   420 			Help();
   421 			help = PR_TRUE;
   422             break;
   423          default:
   424             break;
   425         }
   426     }
   427 	PL_DestroyOptState(opt);
   429     PR_CREATE_TRACE( hTrace, "TraceTest", "tt1", "A description for the trace test" );
   430     mon = PR_NewMonitor();
   431     PR_EnterMonitor( mon );
   433     TraceTest();
   434     CounterTest();
   435     OrderedLockTest();
   437     /* Wait for all threads to exit */
   438     while ( activeThreads > 0 ) {
   439         if ( activeThreads == 1 )
   440             PR_SET_TRACE_OPTION( PRTraceStopRecording, NULL );
   441     	PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
   442         PR_GET_COUNTER( counter, hCounter );
   443     }
   444     PR_ExitMonitor( mon );
   446     /*
   447     ** Evaluate results
   448     */
   449     PR_GET_COUNTER( counter, hCounter );
   450     if ( counter != 0 )
   451     {
   452         failed = PR_TRUE;
   453         PR_LOG( lm, msgLevel,
   454             ("Expected counter == 0, found: %ld", counter));
   455         printf("FAIL\n");
   456     }
   457     else
   458     {
   459         printf("PASS\n");
   460     }
   463     PR_DESTROY_COUNTER( hCounter );
   465     PR_DestroyMonitor( mon );
   467     PR_TRACE( hTrace, TraceFlow, 0xfff,0,0,0,0,0,0);
   468     PR_DESTROY_TRACE( hTrace );
   469 #else
   470     printf("Test not defined\n");
   471 #endif
   472     return 0;
   473 }  /* main() */
   474 /* end instrumt.c */

mercurial