/* 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/. */


/*
 *
 * RWLock tests
 *
 *	Several threads are created to access and modify data arrays using
 * 	PRRWLocks for synchronization. Two data arrays, array_A and array_B, are
 *	initialized with random data and a third array, array_C, is initialized
 *	with the sum of the first 2 arrays.
 *
 *	Each one of the threads acquires a read lock to verify that the sum of
 *	the arrays A and B is equal to array C, and acquires a write lock to
 *	consistently update arrays A and B so that their is equal to array C.
 *		
 */
 
#include "nspr.h"
#include "plgetopt.h"
#include "prrwlock.h"

static int _debug_on;
static void rwtest(void *args);
static PRInt32 *array_A,*array_B,*array_C;
static void update_array(void);
static void check_array(void);

typedef struct thread_args {
	PRRWLock	*rwlock;
	PRInt32		loop_cnt;
} thread_args;

PRFileDesc  *output;
PRFileDesc  *errhandle;

#define	DEFAULT_THREAD_CNT	4
#define	DEFAULT_LOOP_CNT	100
#define	TEST_ARRAY_SIZE		100

int main(int argc, char **argv)
{
    PRInt32 cnt;
	PRStatus rc;
	PRInt32 i;

	PRInt32 thread_cnt = DEFAULT_THREAD_CNT;
	PRInt32 loop_cnt = DEFAULT_LOOP_CNT;
	PRThread **threads;
	thread_args *params;
	PRRWLock	*rwlock1;

	PLOptStatus os;
	PLOptState *opt = PL_CreateOptState(argc, argv, "dt:c:");

	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
    {
		if (PL_OPT_BAD == os) continue;
        switch (opt->option)
        {
        case 'd':  /* debug mode */
			_debug_on = 1;
            break;
        case 't':  /* thread count */
            thread_cnt = atoi(opt->value);
            break;
        case 'c':  /* loop count */
            loop_cnt = atoi(opt->value);
            break;
         default:
            break;
        }
    }
	PL_DestroyOptState(opt);

	PR_SetConcurrency(4);

    output = PR_GetSpecialFD(PR_StandardOutput);
    errhandle = PR_GetSpecialFD(PR_StandardError);

	rwlock1 = PR_NewRWLock(0,"Lock 1");
	if (rwlock1 == NULL) {
		PR_fprintf(errhandle, "PR_NewRWLock failed - error %d\n",
								PR_GetError());
		return 1;
	}

	threads = (PRThread**) PR_CALLOC(sizeof(PRThread*) * thread_cnt);
	params = (thread_args *) PR_CALLOC(sizeof(thread_args) * thread_cnt);

	/*
	 * allocate and initialize data arrays
	 */
	array_A =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE);
	array_B =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE);
	array_C =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE);
	cnt = 0;
	for (i=0; i < TEST_ARRAY_SIZE;i++) {
		array_A[i] = cnt++;
		array_B[i] = cnt++;
		array_C[i] = array_A[i] + array_B[i];
	}

	if (_debug_on)
		PR_fprintf(output,"%s: thread_cnt = %d loop_cnt = %d\n", argv[0],
							thread_cnt, loop_cnt);
	for(cnt = 0; cnt < thread_cnt; cnt++) {
		PRThreadScope scope;

		params[cnt].rwlock = rwlock1;
		params[cnt].loop_cnt = loop_cnt;

		/*
		 * create LOCAL and GLOBAL threads alternately
		 */
		if (cnt & 1)
			scope = PR_LOCAL_THREAD;
		else
			scope = PR_GLOBAL_THREAD;

		threads[cnt] = PR_CreateThread(PR_USER_THREAD,
						  rwtest, &params[cnt],
						  PR_PRIORITY_NORMAL,
						  scope,
						  PR_JOINABLE_THREAD,
						  0);
		if (threads[cnt] == NULL) {
			PR_fprintf(errhandle, "PR_CreateThread failed - error %d\n",
								PR_GetError());
			PR_ProcessExit(2);
		}
		if (_debug_on)
			PR_fprintf(output,"%s: created thread = %p\n", argv[0],
										threads[cnt]);
	}

	for(cnt = 0; cnt < thread_cnt; cnt++) {
    	rc = PR_JoinThread(threads[cnt]);
		PR_ASSERT(rc == PR_SUCCESS);

	}

	PR_DELETE(threads);
	PR_DELETE(params);

	PR_DELETE(array_A);	
	PR_DELETE(array_B);	
	PR_DELETE(array_C);	

	PR_DestroyRWLock(rwlock1);

	
	printf("PASS\n");
	return 0;
}

static void rwtest(void *args)
{
    PRInt32 index;
	thread_args *arg = (thread_args *) args;


	for (index = 0; index < arg->loop_cnt; index++) {

		/*
		 * verify sum, update arrays and verify sum again
		 */

		PR_RWLock_Rlock(arg->rwlock);
		check_array();
		PR_RWLock_Unlock(arg->rwlock);

		PR_RWLock_Wlock(arg->rwlock);
		update_array();
		PR_RWLock_Unlock(arg->rwlock);

		PR_RWLock_Rlock(arg->rwlock);
		check_array();
		PR_RWLock_Unlock(arg->rwlock);
	}
	if (_debug_on)
		PR_fprintf(output,
		"Thread[0x%x] lock = 0x%x exiting\n",
				PR_GetCurrentThread(), arg->rwlock);

}

static void check_array(void)
{
PRInt32 i;

	for (i=0; i < TEST_ARRAY_SIZE;i++)
		if (array_C[i] != (array_A[i] + array_B[i])) {
			PR_fprintf(output, "Error - data check failed\n");
			PR_ProcessExit(1);
		}
}

static void update_array(void)
{
PRInt32 i;

	for (i=0; i < TEST_ARRAY_SIZE;i++) {
		array_A[i] += i;
		array_B[i] -= i;
	}
}
