/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * 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 the Initial Developer are Copyright (C) 1998-2000
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

/*
** 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() */


int main(int 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 */

