~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/nsprpub/pr/tests/rwlocktest.c

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

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