Bug 1845715 - Check for failure when getting RegExp match result template r=iain
[gecko.git] / nsprpub / pr / tests / rwlocktest.c
blob396103c3419496d2fa9f887a3ab9c7775f681ade
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 /*
8 * RWLock tests
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.
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.
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)
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)))
60 if (PL_OPT_BAD == os) {
61 continue;
63 switch (opt->option)
65 case 'd': /* debug mode */
66 _debug_on = 1;
67 break;
68 case 't': /* thread count */
69 thread_cnt = atoi(opt->value);
70 break;
71 case 'c': /* loop count */
72 loop_cnt = atoi(opt->value);
73 break;
74 default:
75 break;
78 PL_DestroyOptState(opt);
80 PR_SetConcurrency(4);
82 output = PR_GetSpecialFD(PR_StandardOutput);
83 errhandle = PR_GetSpecialFD(PR_StandardError);
85 rwlock1 = PR_NewRWLock(0,"Lock 1");
86 if (rwlock1 == NULL) {
87 PR_fprintf(errhandle, "PR_NewRWLock failed - error %d\n",
88 PR_GetError());
89 return 1;
92 threads = (PRThread**) PR_CALLOC(sizeof(PRThread*) * thread_cnt);
93 params = (thread_args *) PR_CALLOC(sizeof(thread_args) * thread_cnt);
96 * allocate and initialize data arrays
98 array_A =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE);
99 array_B =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE);
100 array_C =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE);
101 cnt = 0;
102 for (i=0; i < TEST_ARRAY_SIZE; i++) {
103 array_A[i] = cnt++;
104 array_B[i] = cnt++;
105 array_C[i] = array_A[i] + array_B[i];
108 if (_debug_on)
109 PR_fprintf(output,"%s: thread_cnt = %d loop_cnt = %d\n", argv[0],
110 thread_cnt, loop_cnt);
111 for(cnt = 0; cnt < thread_cnt; cnt++) {
112 PRThreadScope scope;
114 params[cnt].rwlock = rwlock1;
115 params[cnt].loop_cnt = loop_cnt;
118 * create LOCAL and GLOBAL threads alternately
120 if (cnt & 1) {
121 scope = PR_LOCAL_THREAD;
123 else {
124 scope = PR_GLOBAL_THREAD;
127 threads[cnt] = PR_CreateThread(PR_USER_THREAD,
128 rwtest, &params[cnt],
129 PR_PRIORITY_NORMAL,
130 scope,
131 PR_JOINABLE_THREAD,
133 if (threads[cnt] == NULL) {
134 PR_fprintf(errhandle, "PR_CreateThread failed - error %d\n",
135 PR_GetError());
136 PR_ProcessExit(2);
138 if (_debug_on)
139 PR_fprintf(output,"%s: created thread = %p\n", argv[0],
140 threads[cnt]);
143 for(cnt = 0; cnt < thread_cnt; cnt++) {
144 rc = PR_JoinThread(threads[cnt]);
145 PR_ASSERT(rc == PR_SUCCESS);
149 PR_DELETE(threads);
150 PR_DELETE(params);
152 PR_DELETE(array_A);
153 PR_DELETE(array_B);
154 PR_DELETE(array_C);
156 PR_DestroyRWLock(rwlock1);
159 printf("PASS\n");
160 return 0;
163 static void rwtest(void *args)
165 PRInt32 index;
166 thread_args *arg = (thread_args *) args;
169 for (index = 0; index < arg->loop_cnt; index++) {
172 * verify sum, update arrays and verify sum again
175 PR_RWLock_Rlock(arg->rwlock);
176 check_array();
177 PR_RWLock_Unlock(arg->rwlock);
179 PR_RWLock_Wlock(arg->rwlock);
180 update_array();
181 PR_RWLock_Unlock(arg->rwlock);
183 PR_RWLock_Rlock(arg->rwlock);
184 check_array();
185 PR_RWLock_Unlock(arg->rwlock);
187 if (_debug_on)
188 PR_fprintf(output,
189 "Thread[0x%x] lock = 0x%x exiting\n",
190 PR_GetCurrentThread(), arg->rwlock);
194 static void check_array(void)
196 PRInt32 i;
198 for (i=0; i < TEST_ARRAY_SIZE; i++)
199 if (array_C[i] != (array_A[i] + array_B[i])) {
200 PR_fprintf(output, "Error - data check failed\n");
201 PR_ProcessExit(1);
205 static void update_array(void)
207 PRInt32 i;
209 for (i=0; i < TEST_ARRAY_SIZE; i++) {
210 array_A[i] += i;
211 array_B[i] -= i;