/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
** File:        lock.c
** Purpose:     test basic locking functions
**
** Modification History:
** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
**	         The debug mode will print all of the printfs associated with this test.
**			 The regress mode will be the default mode. Since the regress tool limits
**           the output to a one line status:PASS or FAIL,all of the printf statements
**			 have been handled with an if (debug_mode) statement.
** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
**			recognize the return code from tha main program.
**
** 11-Aug-97 LarryH. Win16 port of NSPR.
**           - Added "PASS", "FAIL" messages on completion.
**           - Change stack variables to static scope variables
**             because of shadow-stack use by Win16
**           - Added PR_CALLBACK attribute to functions called by NSPR
**           - Added command line arguments:
**             - l <num> to control the number of loops
**             - c <num> to control the number of CPUs.
**             (was positional argv).
** 
**
***********************************************************************/

/***********************************************************************
** Includes
***********************************************************************/
/* Used to get the command line option */
#include "plgetopt.h"

#include "prio.h"
#include "prcmon.h"
#include "prinit.h"
#include "prinrval.h"
#include "prprf.h"
#include "prlock.h"
#include "prlog.h"
#include "prmon.h"
#include "prmem.h"
#include "prthread.h"
#include "prtypes.h"

#include "plstr.h"

#include <stdlib.h>

#if defined(XP_UNIX)
#include <string.h>
#endif

static PRIntn failed_already=0;
static PRFileDesc *std_err = NULL;
static PRBool verbosity = PR_FALSE;
static PRBool debug_mode = PR_FALSE;

const static PRIntervalTime contention_interval = 50;

typedef struct LockContentious_s {
    PRLock *ml;
    PRInt32 loops;
    PRUint32 contender;
    PRUint32 contentious;
    PRIntervalTime overhead;
    PRIntervalTime interval;
} LockContentious_t;

typedef struct MonitorContentious_s {
    PRMonitor *ml;
    PRInt32 loops;
    PRUint32 contender;
    PRUint32 contentious;
    PRIntervalTime overhead;
    PRIntervalTime interval;
} MonitorContentious_t;


static PRIntervalTime Sleeper(PRUint32 loops)
{
    PRIntervalTime predicted = 0;
    while (loops-- > 0)
    {
        predicted += contention_interval;
        (void)PR_Sleep(contention_interval);
    }
    return predicted;
}  /* Sleeper */

/*
** BASIC LOCKS
*/
static PRIntervalTime MakeLock(PRUint32 loops)
{
    PRLock *ml = NULL;
    while (loops-- > 0)
    {
        ml = PR_NewLock();
        PR_DestroyLock(ml);
        ml = NULL;
    }
    return 0;
}  /* MakeLock */

static PRIntervalTime NonContentiousLock(PRUint32 loops)
{
    PRLock *ml = NULL;
    ml = PR_NewLock();
    while (loops-- > 0)
    {
        PR_Lock(ml);
        PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(ml);
        PR_Unlock(ml);
    }
    PR_DestroyLock(ml);
    return 0;
}  /* NonContentiousLock */

static void PR_CALLBACK LockContender(void *arg)
{
    LockContentious_t *contention = (LockContentious_t*)arg;
    while (contention->loops-- > 0)
    {
        PR_Lock(contention->ml);
        PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(contention->ml);
        contention->contender+= 1;
        contention->overhead += contention->interval;
        PR_Sleep(contention->interval);
        PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(contention->ml);
        PR_Unlock(contention->ml);
    }
}  /* LockContender */

static PRIntervalTime ContentiousLock(PRUint32 loops)
{
    PRStatus status;
    PRThread *thread = NULL;
    LockContentious_t * contention;
    PRIntervalTime rv, overhead, timein = PR_IntervalNow();

    contention = PR_NEWZAP(LockContentious_t);
    contention->loops = loops;
    contention->overhead = 0;
    contention->ml = PR_NewLock();
    contention->interval = contention_interval;
    thread = PR_CreateThread(
        PR_USER_THREAD, LockContender, contention,
        PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
    PR_ASSERT(thread != NULL);

    overhead = PR_IntervalNow() - timein;

    while (contention->loops-- > 0)
    {
        PR_Lock(contention->ml);
        PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(contention->ml);
        contention->contentious+= 1;
        contention->overhead += contention->interval;
        PR_Sleep(contention->interval);
        PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(contention->ml);
        PR_Unlock(contention->ml);
    }

    timein = PR_IntervalNow();
    status = PR_JoinThread(thread);
    PR_DestroyLock(contention->ml);
    overhead += (PR_IntervalNow() - timein);
    rv = overhead + contention->overhead;
    if (verbosity)
        PR_fprintf(
            std_err, "Access ratio: %u to %u\n",
            contention->contentious, contention->contender);
    PR_Free(contention);
    return rv;
}  /* ContentiousLock */

/*
** MONITORS
*/
static PRIntervalTime MakeMonitor(PRUint32 loops)
{
    PRMonitor *ml = NULL;
    while (loops-- > 0)
    {
        ml = PR_NewMonitor();
        PR_DestroyMonitor(ml);
        ml = NULL;
    }
    return 0;
}  /* MakeMonitor */

static PRIntervalTime NonContentiousMonitor(PRUint32 loops)
{
    PRMonitor *ml = NULL;
    ml = PR_NewMonitor();
    while (loops-- > 0)
    {
        PR_EnterMonitor(ml);
        PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml);
        PR_ExitMonitor(ml);
    }
    PR_DestroyMonitor(ml);
    return 0;
}  /* NonContentiousMonitor */

static void PR_CALLBACK TryEntry(void *arg)
{
    PRMonitor *ml = (PRMonitor*)arg;
    if (debug_mode) PR_fprintf(std_err, "Reentrant thread created\n");
    PR_EnterMonitor(ml);
    PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml);
    if (debug_mode) PR_fprintf(std_err, "Reentrant thread acquired monitor\n");
    PR_ExitMonitor(ml);
    if (debug_mode) PR_fprintf(std_err, "Reentrant thread released monitor\n");
}  /* TryEntry */

static PRIntervalTime ReentrantMonitor(PRUint32 loops)
{
    PRStatus status;
    PRThread *thread;
    PRMonitor *ml = PR_NewMonitor();
    if (debug_mode) PR_fprintf(std_err, "\nMonitor created for reentrant test\n");

    PR_EnterMonitor(ml);
    PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml);
    PR_EnterMonitor(ml);
    PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml);
    if (debug_mode) PR_fprintf(std_err, "Monitor acquired twice\n");

    thread = PR_CreateThread(
        PR_USER_THREAD, TryEntry, ml,
        PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
    PR_ASSERT(thread != NULL);
    PR_Sleep(PR_SecondsToInterval(1));
    PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml);

    PR_ExitMonitor(ml);
    PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml);
    if (debug_mode) PR_fprintf(std_err, "Monitor released first time\n");

    PR_ExitMonitor(ml);
    if (debug_mode) PR_fprintf(std_err, "Monitor released second time\n");

    status = PR_JoinThread(thread);
    if (debug_mode) PR_fprintf(std_err, 
        "Reentrant thread joined %s\n",
        (status == PR_SUCCESS) ? "successfully" : "in error");

    PR_DestroyMonitor(ml);
    return 0;
}  /* ReentrantMonitor */

static void PR_CALLBACK MonitorContender(void *arg)
{
    MonitorContentious_t *contention = (MonitorContentious_t*)arg;
    while (contention->loops-- > 0)
    {
        PR_EnterMonitor(contention->ml);
        PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml);
        contention->contender+= 1;
        contention->overhead += contention->interval;
        PR_Sleep(contention->interval);
        PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml);
        PR_ExitMonitor(contention->ml);
    }
}  /* MonitorContender */

static PRUint32 ContentiousMonitor(PRUint32 loops)
{
    PRStatus status;
    PRThread *thread = NULL;
    MonitorContentious_t * contention;
    PRIntervalTime rv, overhead, timein = PR_IntervalNow();

    contention = PR_NEWZAP(MonitorContentious_t);
    contention->loops = loops;
    contention->overhead = 0;
    contention->ml = PR_NewMonitor();
    contention->interval = contention_interval;
    thread = PR_CreateThread(
        PR_USER_THREAD, MonitorContender, contention,
        PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
    PR_ASSERT(thread != NULL);

    overhead = PR_IntervalNow() - timein;

    while (contention->loops-- > 0)
    {
        PR_EnterMonitor(contention->ml);
        PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml);
        contention->contentious+= 1;
        contention->overhead += contention->interval;
        PR_Sleep(contention->interval);
        PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml);
        PR_ExitMonitor(contention->ml);
    }

    timein = PR_IntervalNow();
    status = PR_JoinThread(thread);
    PR_DestroyMonitor(contention->ml);
    overhead += (PR_IntervalNow() - timein);
    rv = overhead + contention->overhead;
    if (verbosity)
        PR_fprintf(
            std_err, "Access ratio: %u to %u\n",
            contention->contentious, contention->contender);
    PR_Free(contention);
    return rv;
}  /* ContentiousMonitor */

/*
** CACHED MONITORS
*/
static PRIntervalTime NonContentiousCMonitor(PRUint32 loops)
{
    MonitorContentious_t contention;
    while (loops-- > 0)
    {
        PR_CEnterMonitor(&contention);
        PR_CExitMonitor(&contention);
    }
    return 0;
}  /* NonContentiousCMonitor */

static void PR_CALLBACK Contender(void *arg)
{
    MonitorContentious_t *contention = (MonitorContentious_t*)arg;
    while (contention->loops-- > 0)
    {
        PR_CEnterMonitor(contention);
        contention->contender+= 1;
        contention->overhead += contention->interval;
        PR_Sleep(contention->interval);
        PR_CExitMonitor(contention);
    }
}  /* Contender */

static PRIntervalTime ContentiousCMonitor(PRUint32 loops)
{
    PRStatus status;
    PRThread *thread = NULL;
    MonitorContentious_t * contention;
    PRIntervalTime overhead, timein = PR_IntervalNow();

    contention = PR_NEWZAP(MonitorContentious_t);
    contention->ml = NULL;
    contention->loops = loops;
    contention->interval = contention_interval;
    thread = PR_CreateThread(
        PR_USER_THREAD, Contender, contention,
        PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
    PR_ASSERT(thread != NULL);

    overhead = PR_IntervalNow() - timein;

    while (contention->loops-- > 0)
    {
        PR_CEnterMonitor(contention);
        contention->contentious+= 1;
        contention->overhead += contention->interval;
        PR_Sleep(contention->interval);
        PR_CExitMonitor(contention);
    }

    timein = PR_IntervalNow();
    status = PR_JoinThread(thread);
    overhead += (PR_IntervalNow() - timein);
    overhead += overhead + contention->overhead;
    if (verbosity)
        PR_fprintf(
            std_err, "Access ratio: %u to %u\n",
            contention->contentious, contention->contender);
    PR_Free(contention);
    return overhead;
}  /* ContentiousCMonitor */

static PRIntervalTime Test(
    const char* msg, PRUint32 (*test)(PRUint32 loops),
    PRUint32 loops, PRIntervalTime overhead)
{ 
    /*
     * overhead - overhead not measured by the test.
     * duration - wall clock time it took to perform test.
     * predicted - extra time test says should not be counted 
     *
     * Time accountable to the test is duration - overhead - predicted
     * All times are Intervals and accumulated for all iterations.
     */
    PRFloat64 elapsed;
    PRIntervalTime accountable, duration;    
    PRUintn spaces = PL_strlen(msg);
    PRIntervalTime timeout, timein = PR_IntervalNow();
    PRIntervalTime predicted = test(loops);
    timeout = PR_IntervalNow();
    duration = timeout - timein;

    if (debug_mode)
    {
        accountable = duration - predicted;
        accountable -= overhead;
        elapsed = (PRFloat64)PR_IntervalToMicroseconds(accountable);
        PR_fprintf(PR_STDOUT, "%s:", msg);
        while (spaces++ < 50) PR_fprintf(PR_STDOUT, " ");
        if ((PRInt32)accountable < 0)
            PR_fprintf(PR_STDOUT, "*****.** usecs/iteration\n");
        else
            PR_fprintf(PR_STDOUT, "%8.2f usecs/iteration\n", elapsed/loops);
    }
    return duration;
}  /* Test */

int main(int argc,  char **argv)
{
    PRBool rv = PR_TRUE;
    PRIntervalTime duration;
    PRUint32 cpu, cpus = 2, loops = 100;

	
    PR_STDIO_INIT();
    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
    {
    	/* The command line argument: -d is used to determine if the test is being run
    	in debug mode. The regress tool requires only one line output:PASS or FAIL.
    	All of the printfs associated with this test has been handled with a if (debug_mode)
    	test.
        Command line argument -l <num> sets the number of loops.
        Command line argument -c <num> sets the number of cpus.
        Usage: lock [-d] [-l <num>] [-c <num>]
    	*/
    	PLOptStatus os;
    	PLOptState *opt = PL_CreateOptState(argc, argv, "dvl:c:");
    	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
        {
    		if (PL_OPT_BAD == os) continue;
            switch (opt->option)
            {
            case 'd':  /* debug mode */
    			debug_mode = PR_TRUE;
                break;
            case 'v':  /* debug mode */
    			verbosity = PR_TRUE;
                break;
            case 'l':  /* number of loops */
                loops = atoi(opt->value);
                break;
            case 'c':  /* number of cpus */
                cpus = atoi(opt->value);
                break;
             default:
                break;
            }
        }
    	PL_DestroyOptState(opt);
    }

 /* main test */
    PR_SetConcurrency(8);

    if (loops == 0) loops = 100;
    if (debug_mode)
    {
        std_err = PR_STDERR;
        PR_fprintf(std_err, "Lock: Using %d loops\n", loops);
    }

    if (cpus == 0) cpus = 2;
    if (debug_mode) PR_fprintf(std_err, "Lock: Using %d cpu(s)\n", cpus);

    (void)Sleeper(10);  /* try filling in the caches */

    for (cpu = 1; cpu <= cpus; ++cpu)
    {
        if (debug_mode) PR_fprintf(std_err, "\nLock: Using %d CPU(s)\n", cpu);
        PR_SetConcurrency(cpu);

        duration = Test("Overhead of PR_Sleep", Sleeper, loops, 0);
        duration = 0;

        (void)Test("Lock creation/deletion", MakeLock, loops, 0);
        (void)Test("Lock non-contentious locking/unlocking", NonContentiousLock, loops, 0);
        (void)Test("Lock contentious locking/unlocking", ContentiousLock, loops, duration);
        (void)Test("Monitor creation/deletion", MakeMonitor, loops, 0);
        (void)Test("Monitor non-contentious locking/unlocking", NonContentiousMonitor, loops, 0);
        (void)Test("Monitor contentious locking/unlocking", ContentiousMonitor, loops, duration);

        (void)Test("Cached monitor non-contentious locking/unlocking", NonContentiousCMonitor, loops, 0);
        (void)Test("Cached monitor contentious locking/unlocking", ContentiousCMonitor, loops, duration);

        (void)ReentrantMonitor(loops);
    }

    if (debug_mode)
        PR_fprintf(
            std_err, "%s: test %s\n", "Lock(mutex) test",
            ((rv) ? "passed" : "failed"));
	else {
		 if (!rv)
			 failed_already=1;
	}

	if(failed_already)	
	{
	    PR_fprintf(PR_STDOUT, "FAIL\n"); 
		return 1;
    } 
	else
    {
	    PR_fprintf(PR_STDOUT, "PASS\n"); 
		return 0;
    }

}  /* main */

/* testlock.c */
