VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/nsprpub/pr/tests/rwlocktest.c@ 1

Last change on this file since 1 was 1, checked in by vboxsync, 55 years ago

import

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.1 KB
Line 
1/* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3 *
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
8 *
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
13 *
14 * The Original Code is the Netscape Portable Runtime (NSPR).
15 *
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1998-2000
19 * the Initial Developer. All Rights Reserved.
20 *
21 * Contributor(s):
22 *
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
34 *
35 * ***** END LICENSE BLOCK ***** */
36
37
38/*
39 *
40 * RWLock tests
41 *
42 * Several threads are created to access and modify data arrays using
43 * PRRWLocks for synchronization. Two data arrays, array_A and array_B, are
44 * initialized with random data and a third array, array_C, is initialized
45 * with the sum of the first 2 arrays.
46 *
47 * Each one of the threads acquires a read lock to verify that the sum of
48 * the arrays A and B is equal to array C, and acquires a write lock to
49 * consistently update arrays A and B so that their is equal to array C.
50 *
51 */
52
53#include "nspr.h"
54#include "plgetopt.h"
55#include "prrwlock.h"
56
57static int _debug_on;
58static void rwtest(void *args);
59static PRInt32 *array_A,*array_B,*array_C;
60static void update_array(void);
61static void check_array(void);
62
63typedef struct thread_args {
64 PRRWLock *rwlock;
65 PRInt32 loop_cnt;
66} thread_args;
67
68PRFileDesc *output;
69PRFileDesc *errhandle;
70
71#define DEFAULT_THREAD_CNT 4
72#define DEFAULT_LOOP_CNT 100
73#define TEST_ARRAY_SIZE 100
74
75PRIntn main(PRIntn argc, char **argv)
76{
77 PRInt32 cnt;
78 PRStatus rc;
79 PRInt32 i;
80
81 PRInt32 thread_cnt = DEFAULT_THREAD_CNT;
82 PRInt32 loop_cnt = DEFAULT_LOOP_CNT;
83 PRThread **threads;
84 thread_args *params;
85 PRRWLock *rwlock1;
86
87 PLOptStatus os;
88 PLOptState *opt = PL_CreateOptState(argc, argv, "dt:c:");
89
90 while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
91 {
92 if (PL_OPT_BAD == os) continue;
93 switch (opt->option)
94 {
95 case 'd': /* debug mode */
96 _debug_on = 1;
97 break;
98 case 't': /* thread count */
99 thread_cnt = atoi(opt->value);
100 break;
101 case 'c': /* loop count */
102 loop_cnt = atoi(opt->value);
103 break;
104 default:
105 break;
106 }
107 }
108 PL_DestroyOptState(opt);
109
110 PR_SetConcurrency(4);
111
112 output = PR_GetSpecialFD(PR_StandardOutput);
113 errhandle = PR_GetSpecialFD(PR_StandardError);
114
115 rwlock1 = PR_NewRWLock(0,"Lock 1");
116 if (rwlock1 == NULL) {
117 PR_fprintf(errhandle, "PR_NewRWLock failed - error %d\n",
118 PR_GetError());
119 return 1;
120 }
121
122 threads = (PRThread**) PR_CALLOC(sizeof(PRThread*) * thread_cnt);
123 params = (thread_args *) PR_CALLOC(sizeof(thread_args) * thread_cnt);
124
125 /*
126 * allocate and initialize data arrays
127 */
128 array_A =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE);
129 array_B =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE);
130 array_C =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE);
131 cnt = 0;
132 for (i=0; i < TEST_ARRAY_SIZE;i++) {
133 array_A[i] = cnt++;
134 array_B[i] = cnt++;
135 array_C[i] = array_A[i] + array_B[i];
136 }
137
138 if (_debug_on)
139 PR_fprintf(output,"%s: thread_cnt = %d loop_cnt = %d\n", argv[0],
140 thread_cnt, loop_cnt);
141 for(cnt = 0; cnt < thread_cnt; cnt++) {
142 PRThreadScope scope;
143
144 params[cnt].rwlock = rwlock1;
145 params[cnt].loop_cnt = loop_cnt;
146
147 /*
148 * create LOCAL and GLOBAL threads alternately
149 */
150 if (cnt & 1)
151 scope = PR_LOCAL_THREAD;
152 else
153 scope = PR_GLOBAL_THREAD;
154
155 threads[cnt] = PR_CreateThread(PR_USER_THREAD,
156 rwtest, &params[cnt],
157 PR_PRIORITY_NORMAL,
158 scope,
159 PR_JOINABLE_THREAD,
160 0);
161 if (threads[cnt] == NULL) {
162 PR_fprintf(errhandle, "PR_CreateThread failed - error %d\n",
163 PR_GetError());
164 PR_ProcessExit(2);
165 }
166 if (_debug_on)
167 PR_fprintf(output,"%s: created thread = 0x%x\n", argv[0],
168 threads[cnt]);
169 }
170
171 for(cnt = 0; cnt < thread_cnt; cnt++) {
172 rc = PR_JoinThread(threads[cnt]);
173 PR_ASSERT(rc == PR_SUCCESS);
174
175 }
176
177 PR_DELETE(threads);
178 PR_DELETE(params);
179
180 PR_DELETE(array_A);
181 PR_DELETE(array_B);
182 PR_DELETE(array_C);
183
184 PR_DestroyRWLock(rwlock1);
185
186
187 printf("PASS\n");
188 return 0;
189}
190
191static void rwtest(void *args)
192{
193 PRInt32 index;
194 thread_args *arg = (thread_args *) args;
195
196
197 for (index = 0; index < arg->loop_cnt; index++) {
198
199 /*
200 * verify sum, update arrays and verify sum again
201 */
202
203 PR_RWLock_Rlock(arg->rwlock);
204 check_array();
205 PR_RWLock_Unlock(arg->rwlock);
206
207 PR_RWLock_Wlock(arg->rwlock);
208 update_array();
209 PR_RWLock_Unlock(arg->rwlock);
210
211 PR_RWLock_Rlock(arg->rwlock);
212 check_array();
213 PR_RWLock_Unlock(arg->rwlock);
214 }
215 if (_debug_on)
216 PR_fprintf(output,
217 "Thread[0x%x] lock = 0x%x exiting\n",
218 PR_GetCurrentThread(), arg->rwlock);
219
220}
221
222static void check_array(void)
223{
224PRInt32 i;
225
226 for (i=0; i < TEST_ARRAY_SIZE;i++)
227 if (array_C[i] != (array_A[i] + array_B[i])) {
228 PR_fprintf(output, "Error - data check failed\n");
229 PR_ProcessExit(1);
230 }
231}
232
233static void update_array(void)
234{
235PRInt32 i;
236
237 for (i=0; i < TEST_ARRAY_SIZE;i++) {
238 array_A[i] += i;
239 array_B[i] -= i;
240 }
241}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette