nsprpub/pr/tests/rwlocktest.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 /*
     7  *
     8  * RWLock tests
     9  *
    10  *	Several threads are created to access and modify data arrays using
    11  * 	PRRWLocks for synchronization. Two data arrays, array_A and array_B, are
    12  *	initialized with random data and a third array, array_C, is initialized
    13  *	with the sum of the first 2 arrays.
    14  *
    15  *	Each one of the threads acquires a read lock to verify that the sum of
    16  *	the arrays A and B is equal to array C, and acquires a write lock to
    17  *	consistently update arrays A and B so that their is equal to array C.
    18  *		
    19  */
    21 #include "nspr.h"
    22 #include "plgetopt.h"
    23 #include "prrwlock.h"
    25 static int _debug_on;
    26 static void rwtest(void *args);
    27 static PRInt32 *array_A,*array_B,*array_C;
    28 static void update_array(void);
    29 static void check_array(void);
    31 typedef struct thread_args {
    32 	PRRWLock	*rwlock;
    33 	PRInt32		loop_cnt;
    34 } thread_args;
    36 PRFileDesc  *output;
    37 PRFileDesc  *errhandle;
    39 #define	DEFAULT_THREAD_CNT	4
    40 #define	DEFAULT_LOOP_CNT	100
    41 #define	TEST_ARRAY_SIZE		100
    43 int main(int argc, char **argv)
    44 {
    45     PRInt32 cnt;
    46 	PRStatus rc;
    47 	PRInt32 i;
    49 	PRInt32 thread_cnt = DEFAULT_THREAD_CNT;
    50 	PRInt32 loop_cnt = DEFAULT_LOOP_CNT;
    51 	PRThread **threads;
    52 	thread_args *params;
    53 	PRRWLock	*rwlock1;
    55 	PLOptStatus os;
    56 	PLOptState *opt = PL_CreateOptState(argc, argv, "dt:c:");
    58 	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
    59     {
    60 		if (PL_OPT_BAD == os) continue;
    61         switch (opt->option)
    62         {
    63         case 'd':  /* debug mode */
    64 			_debug_on = 1;
    65             break;
    66         case 't':  /* thread count */
    67             thread_cnt = atoi(opt->value);
    68             break;
    69         case 'c':  /* loop count */
    70             loop_cnt = atoi(opt->value);
    71             break;
    72          default:
    73             break;
    74         }
    75     }
    76 	PL_DestroyOptState(opt);
    78 	PR_SetConcurrency(4);
    80     output = PR_GetSpecialFD(PR_StandardOutput);
    81     errhandle = PR_GetSpecialFD(PR_StandardError);
    83 	rwlock1 = PR_NewRWLock(0,"Lock 1");
    84 	if (rwlock1 == NULL) {
    85 		PR_fprintf(errhandle, "PR_NewRWLock failed - error %d\n",
    86 								PR_GetError());
    87 		return 1;
    88 	}
    90 	threads = (PRThread**) PR_CALLOC(sizeof(PRThread*) * thread_cnt);
    91 	params = (thread_args *) PR_CALLOC(sizeof(thread_args) * thread_cnt);
    93 	/*
    94 	 * allocate and initialize data arrays
    95 	 */
    96 	array_A =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE);
    97 	array_B =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE);
    98 	array_C =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE);
    99 	cnt = 0;
   100 	for (i=0; i < TEST_ARRAY_SIZE;i++) {
   101 		array_A[i] = cnt++;
   102 		array_B[i] = cnt++;
   103 		array_C[i] = array_A[i] + array_B[i];
   104 	}
   106 	if (_debug_on)
   107 		PR_fprintf(output,"%s: thread_cnt = %d loop_cnt = %d\n", argv[0],
   108 							thread_cnt, loop_cnt);
   109 	for(cnt = 0; cnt < thread_cnt; cnt++) {
   110 		PRThreadScope scope;
   112 		params[cnt].rwlock = rwlock1;
   113 		params[cnt].loop_cnt = loop_cnt;
   115 		/*
   116 		 * create LOCAL and GLOBAL threads alternately
   117 		 */
   118 		if (cnt & 1)
   119 			scope = PR_LOCAL_THREAD;
   120 		else
   121 			scope = PR_GLOBAL_THREAD;
   123 		threads[cnt] = PR_CreateThread(PR_USER_THREAD,
   124 						  rwtest, &params[cnt],
   125 						  PR_PRIORITY_NORMAL,
   126 						  scope,
   127 						  PR_JOINABLE_THREAD,
   128 						  0);
   129 		if (threads[cnt] == NULL) {
   130 			PR_fprintf(errhandle, "PR_CreateThread failed - error %d\n",
   131 								PR_GetError());
   132 			PR_ProcessExit(2);
   133 		}
   134 		if (_debug_on)
   135 			PR_fprintf(output,"%s: created thread = %p\n", argv[0],
   136 										threads[cnt]);
   137 	}
   139 	for(cnt = 0; cnt < thread_cnt; cnt++) {
   140     	rc = PR_JoinThread(threads[cnt]);
   141 		PR_ASSERT(rc == PR_SUCCESS);
   143 	}
   145 	PR_DELETE(threads);
   146 	PR_DELETE(params);
   148 	PR_DELETE(array_A);	
   149 	PR_DELETE(array_B);	
   150 	PR_DELETE(array_C);	
   152 	PR_DestroyRWLock(rwlock1);
   155 	printf("PASS\n");
   156 	return 0;
   157 }
   159 static void rwtest(void *args)
   160 {
   161     PRInt32 index;
   162 	thread_args *arg = (thread_args *) args;
   165 	for (index = 0; index < arg->loop_cnt; index++) {
   167 		/*
   168 		 * verify sum, update arrays and verify sum again
   169 		 */
   171 		PR_RWLock_Rlock(arg->rwlock);
   172 		check_array();
   173 		PR_RWLock_Unlock(arg->rwlock);
   175 		PR_RWLock_Wlock(arg->rwlock);
   176 		update_array();
   177 		PR_RWLock_Unlock(arg->rwlock);
   179 		PR_RWLock_Rlock(arg->rwlock);
   180 		check_array();
   181 		PR_RWLock_Unlock(arg->rwlock);
   182 	}
   183 	if (_debug_on)
   184 		PR_fprintf(output,
   185 		"Thread[0x%x] lock = 0x%x exiting\n",
   186 				PR_GetCurrentThread(), arg->rwlock);
   188 }
   190 static void check_array(void)
   191 {
   192 PRInt32 i;
   194 	for (i=0; i < TEST_ARRAY_SIZE;i++)
   195 		if (array_C[i] != (array_A[i] + array_B[i])) {
   196 			PR_fprintf(output, "Error - data check failed\n");
   197 			PR_ProcessExit(1);
   198 		}
   199 }
   201 static void update_array(void)
   202 {
   203 PRInt32 i;
   205 	for (i=0; i < TEST_ARRAY_SIZE;i++) {
   206 		array_A[i] += i;
   207 		array_B[i] -= i;
   208 	}
   209 }

mercurial