VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTSemRW.cpp@ 25614

Last change on this file since 25614 was 25524, checked in by vboxsync, 15 years ago

semrw-posix.cpp,tstRTSemRW: added an insufficient workaround for the glibc pthread_rwlock_unlock issue.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 19.9 KB
Line 
1/* $Id: tstRTSemRW.cpp 25524 2009-12-20 16:56:30Z vboxsync $ */
2/** @file
3 * IPRT Testcase - Reader/Writer Semaphore.
4 */
5
6/*
7 * Copyright (C) 2009 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 *
26 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27 * Clara, CA 95054 USA or visit http://www.sun.com if you need
28 * additional information or have any questions.
29 */
30
31/*******************************************************************************
32* Header Files *
33*******************************************************************************/
34#include <iprt/semaphore.h>
35
36#include <iprt/asm.h>
37#include <iprt/assert.h>
38#include <iprt/err.h>
39#include <iprt/initterm.h>
40#include <iprt/lockvalidator.h>
41#include <iprt/rand.h>
42#include <iprt/string.h>
43#include <iprt/stream.h>
44#include <iprt/test.h>
45#include <iprt/time.h>
46#include <iprt/thread.h>
47
48
49/*******************************************************************************
50* Global Variables *
51*******************************************************************************/
52static RTTEST g_hTest;
53static RTSEMRW g_hSemRW = NIL_RTSEMRW;
54static bool volatile g_fTerminate;
55static bool g_fYield;
56static bool g_fQuiet;
57static unsigned g_uWritePercent;
58static uint32_t volatile g_cConcurrentWriters;
59static uint32_t volatile g_cConcurrentReaders;
60
61
62static DECLCALLBACK(int) Test4Thread(RTTHREAD ThreadSelf, void *pvUser)
63{
64 /* Use randomization to get a little more variation of the sync pattern.
65 We use a pseudo random generator here so that we don't end up testing
66 the speed of the /dev/urandom implementation, but rather the read-write
67 semaphores. */
68 int rc;
69 RTRAND hRand;
70 RTTEST_CHECK_RC_OK_RET(g_hTest, rc = RTRandAdvCreateParkMiller(&hRand), rc);
71 RTTEST_CHECK_RC_OK_RET(g_hTest, rc = RTRandAdvSeed(hRand, (uintptr_t)ThreadSelf), rc);
72 unsigned c100 = RTRandAdvU32Ex(hRand, 0, 99);
73
74 uint64_t *pcItr = (uint64_t *)pvUser;
75 bool fWrite;
76 for (;;)
77 {
78 unsigned readrec = RTRandAdvU32Ex(hRand, 0, 3);
79 unsigned writerec = RTRandAdvU32Ex(hRand, 0, 3);
80 /* Don't overdo recursion testing. */
81 if (readrec > 1)
82 readrec--;
83 if (writerec > 1)
84 writerec--;
85
86 fWrite = (c100 < g_uWritePercent);
87 if (fWrite)
88 {
89 for (unsigned i = 0; i <= writerec; i++)
90 {
91 rc = RTSemRWRequestWriteNoResume(g_hSemRW, RT_INDEFINITE_WAIT);
92 if (RT_FAILURE(rc))
93 {
94 RTTestFailed(g_hTest, "Write recursion %u on %s failed with rc=%Rrc", i, RTThreadSelfName(), rc);
95 break;
96 }
97 }
98 if (RT_FAILURE(rc))
99 break;
100 if (ASMAtomicIncU32(&g_cConcurrentWriters) != 1)
101 {
102 RTTestFailed(g_hTest, "g_cConcurrentWriters=%u on %s after write locking it",
103 g_cConcurrentWriters, RTThreadSelfName());
104 break;
105 }
106 if (g_cConcurrentReaders != 0)
107 {
108 RTTestFailed(g_hTest, "g_cConcurrentReaders=%u on %s after write locking it",
109 g_cConcurrentReaders, RTThreadSelfName());
110 break;
111 }
112 }
113 else
114 {
115 rc = RTSemRWRequestReadNoResume(g_hSemRW, RT_INDEFINITE_WAIT);
116 if (RT_FAILURE(rc))
117 {
118 RTTestFailed(g_hTest, "Read locking on %s failed with rc=%Rrc", RTThreadSelfName(), rc);
119 break;
120 }
121 ASMAtomicIncU32(&g_cConcurrentReaders);
122 if (g_cConcurrentWriters != 0)
123 {
124 RTTestFailed(g_hTest, "g_cConcurrentWriters=%u on %s after read locking it",
125 g_cConcurrentWriters, RTThreadSelfName());
126 break;
127 }
128 }
129 for (unsigned i = 0; i < readrec; i++)
130 {
131 rc = RTSemRWRequestReadNoResume(g_hSemRW, RT_INDEFINITE_WAIT);
132 if (RT_FAILURE(rc))
133 {
134 RTTestFailed(g_hTest, "Read recursion %u on %s failed with rc=%Rrc", i, RTThreadSelfName(), rc);
135 break;
136 }
137 }
138 if (RT_FAILURE(rc))
139 break;
140
141 /*
142 * Check for fairness: The values of the threads should not differ too much
143 */
144 (*pcItr)++;
145
146 /*
147 * Check for correctness: Give other threads a chance. If the implementation is
148 * correct, no other thread will be able to enter this lock now.
149 */
150 if (g_fYield)
151 RTThreadYield();
152
153 for (unsigned i = 0; i < readrec; i++)
154 {
155 rc = RTSemRWReleaseRead(g_hSemRW);
156 if (RT_FAILURE(rc))
157 {
158 RTTestFailed(g_hTest, "Read release %u on %s failed with rc=%Rrc", i, RTThreadSelfName(), rc);
159 break;
160 }
161 }
162 if (RT_FAILURE(rc))
163 break;
164
165 if (fWrite)
166 {
167 if (ASMAtomicDecU32(&g_cConcurrentWriters) != 0)
168 {
169 RTTestFailed(g_hTest, "g_cConcurrentWriters=%u on %s before write release",
170 g_cConcurrentWriters, RTThreadSelfName());
171 break;
172 }
173 if (g_cConcurrentReaders != 0)
174 {
175 RTTestFailed(g_hTest, "g_cConcurrentReaders=%u on %s before write release",
176 g_cConcurrentReaders, RTThreadSelfName());
177 break;
178 }
179 for (unsigned i = 0; i <= writerec; i++)
180 {
181 rc = RTSemRWReleaseWrite(g_hSemRW);
182 if (RT_FAILURE(rc))
183 {
184 RTTestFailed(g_hTest, "Write release %u on %s failed with rc=%Rrc", i, RTThreadSelfName(), rc);
185 break;
186 }
187 }
188 }
189 else
190 {
191 if (g_cConcurrentWriters != 0)
192 {
193 RTTestFailed(g_hTest, "g_cConcurrentWriters=%u on %s before read release",
194 g_cConcurrentWriters, RTThreadSelfName());
195 break;
196 }
197 ASMAtomicDecU32(&g_cConcurrentReaders);
198 rc = RTSemRWReleaseRead(g_hSemRW);
199 if (RT_FAILURE(rc))
200 {
201 RTTestFailed(g_hTest, "Read release on %s failed with rc=%Rrc", RTThreadSelfName(), rc);
202 break;
203 }
204 }
205
206 if (g_fTerminate)
207 break;
208
209 c100++;
210 c100 %= 100;
211 }
212 if (!g_fQuiet)
213 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Thread %s exited with %lld\n", RTThreadSelfName(), *pcItr);
214 RTRandAdvDestroy(hRand);
215 return VINF_SUCCESS;
216}
217
218
219static void Test4(unsigned cThreads, unsigned cSeconds, unsigned uWritePercent, bool fYield, bool fQuiet)
220{
221 int rc;
222 unsigned i;
223 uint64_t acIterations[32];
224 RTTHREAD aThreads[RT_ELEMENTS(acIterations)];
225 AssertRelease(cThreads <= RT_ELEMENTS(acIterations));
226
227 RTTestSubF(g_hTest, "Test4 - %u threads, %u sec, %u%% writes, %syielding",
228 cThreads, cSeconds, uWritePercent, fYield ? "" : "non-");
229
230 /*
231 * Init globals.
232 */
233 g_fYield = fYield;
234 g_fQuiet = fQuiet;
235 g_fTerminate = false;
236 g_uWritePercent = uWritePercent;
237 g_cConcurrentWriters = 0;
238 g_cConcurrentReaders = 0;
239
240 RTTEST_CHECK_RC_RETV(g_hTest, RTSemRWCreate(&g_hSemRW), VINF_SUCCESS);
241
242 /*
243 * Create the threads and let them block on the semrw.
244 */
245 RTTEST_CHECK_RC_RETV(g_hTest, RTSemRWRequestWrite(g_hSemRW, RT_INDEFINITE_WAIT), VINF_SUCCESS);
246
247 for (i = 0; i < cThreads; i++)
248 {
249 acIterations[i] = 0;
250 RTTEST_CHECK_RC_RETV(g_hTest, RTThreadCreateF(&aThreads[i], Test4Thread, &acIterations[i], 0,
251 RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE,
252 "test-%u", i), VINF_SUCCESS);
253 }
254
255 /*
256 * Do the test run.
257 */
258 uint32_t cErrorsBefore = RTTestErrorCount(g_hTest);
259 uint64_t u64StartTS = RTTimeNanoTS();
260 RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseWrite(g_hSemRW), VINF_SUCCESS);
261 RTThreadSleep(cSeconds * 1000);
262 ASMAtomicWriteBool(&g_fTerminate, true);
263 uint64_t ElapsedNS = RTTimeNanoTS() - u64StartTS;
264
265 /*
266 * Clean up the threads and semaphore.
267 */
268 for (i = 0; i < cThreads; i++)
269 RTTEST_CHECK_RC(g_hTest, RTThreadWait(aThreads[i], 5000, NULL), VINF_SUCCESS);
270
271 RTTEST_CHECK_MSG(g_hTest, g_cConcurrentWriters == 0, (g_hTest, "g_cConcurrentWriters=%u at end of test\n", g_cConcurrentWriters));
272 RTTEST_CHECK_MSG(g_hTest, g_cConcurrentReaders == 0, (g_hTest, "g_cConcurrentReaders=%u at end of test\n", g_cConcurrentReaders));
273
274 RTTEST_CHECK_RC(g_hTest, RTSemRWDestroy(g_hSemRW), VINF_SUCCESS);
275 g_hSemRW = NIL_RTSEMRW;
276
277 if (RTTestErrorCount(g_hTest) != cErrorsBefore)
278 RTThreadSleep(100);
279
280 /*
281 * Collect and display the results.
282 */
283 uint64_t cItrTotal = acIterations[0];
284 for (i = 1; i < cThreads; i++)
285 cItrTotal += acIterations[i];
286
287 uint64_t cItrNormal = cItrTotal / cThreads;
288 uint64_t cItrMinOK = cItrNormal / 20; /* 5% */
289 uint64_t cItrMaxDeviation = 0;
290 for (i = 0; i < cThreads; i++)
291 {
292 uint64_t cItrDelta = RT_ABS((int64_t)(acIterations[i] - cItrNormal));
293 if (acIterations[i] < cItrMinOK)
294 RTTestFailed(g_hTest, "Thread %u did less than 5%% of the iterations - %llu (it) vs. %llu (5%%) - %llu%%\n",
295 i, acIterations[i], cItrMinOK, cItrDelta * 100 / cItrNormal);
296 else if (cItrDelta > cItrNormal / 2)
297 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS,
298 "Warning! Thread %u deviates by more than 50%% - %llu (it) vs. %llu (avg) - %llu%%\n",
299 i, acIterations[i], cItrNormal, cItrDelta * 100 / cItrNormal);
300 if (cItrDelta > cItrMaxDeviation)
301 cItrMaxDeviation = cItrDelta;
302
303 }
304
305 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS,
306 "Threads: %u Total: %llu Per Sec: %llu Avg: %llu ns Max dev: %llu%%\n",
307 cThreads,
308 cItrTotal,
309 cItrTotal / cSeconds,
310 ElapsedNS / cItrTotal,
311 cItrMaxDeviation * 100 / cItrNormal
312 );
313}
314
315
316static DECLCALLBACK(int) Test2Thread(RTTHREAD hThreadSelf, void *pvUser)
317{
318 RTSEMRW hSemRW = (RTSEMRW)pvUser;
319
320 RTTEST_CHECK_RC(g_hTest, RTSemRWRequestRead(hSemRW, 0), VERR_TIMEOUT);
321 RTTEST_CHECK_RC(g_hTest, RTSemRWRequestWrite(hSemRW, 0), VERR_TIMEOUT);
322
323 RTTEST_CHECK_RC(g_hTest, RTSemRWRequestRead(hSemRW, 1), VERR_TIMEOUT);
324 RTTEST_CHECK_RC(g_hTest, RTSemRWRequestWrite(hSemRW, 1), VERR_TIMEOUT);
325
326 RTTEST_CHECK_RC(g_hTest, RTSemRWRequestRead(hSemRW, 50), VERR_TIMEOUT);
327 RTTEST_CHECK_RC(g_hTest, RTSemRWRequestWrite(hSemRW, 50), VERR_TIMEOUT);
328
329 return VINF_SUCCESS;
330}
331
332
333static void Test3(void)
334{
335 RTTestSub(g_hTest, "Negative");
336 bool fSavedAssertQuiet = RTAssertSetQuiet(true);
337 bool fSavedAssertMayPanic = RTAssertSetMayPanic(false);
338 bool fSavedLckValEnabled = RTLockValidatorSetEnabled(false);
339
340 RTSEMRW hSemRW;
341 RTTEST_CHECK_RC_RETV(g_hTest, RTSemRWCreate(&hSemRW), VINF_SUCCESS);
342
343 RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseRead(hSemRW), VERR_NOT_OWNER);
344 RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseWrite(hSemRW), VERR_NOT_OWNER);
345
346 RTTEST_CHECK_RC(g_hTest, RTSemRWRequestWrite(hSemRW, RT_INDEFINITE_WAIT), VINF_SUCCESS);
347 RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseRead(hSemRW), VERR_NOT_OWNER);
348
349 RTTEST_CHECK_RC(g_hTest, RTSemRWRequestRead(hSemRW, RT_INDEFINITE_WAIT), VINF_SUCCESS);
350 RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseWrite(hSemRW), VERR_WRONG_ORDER); /* cannot release the final write before the reads. */
351 RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseRead(hSemRW), VINF_SUCCESS);
352 RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseWrite(hSemRW), VINF_SUCCESS);
353
354 RTTEST_CHECK_RC(g_hTest, RTSemRWDestroy(hSemRW), VINF_SUCCESS);
355
356 RTLockValidatorSetEnabled(fSavedLckValEnabled);
357 RTAssertSetMayPanic(fSavedAssertMayPanic);
358 RTAssertSetQuiet(fSavedAssertQuiet);
359}
360
361static void Test2(void)
362{
363 RTTestSub(g_hTest, "Timeout");
364
365 RTSEMRW hSemRW = NIL_RTSEMRW;
366 RTTEST_CHECK_RC_RETV(g_hTest, RTSemRWCreate(&hSemRW), VINF_SUCCESS);
367
368 /* Lock it for writing and let the thread do the remainder of the test. */
369 RTTEST_CHECK_RC_RETV(g_hTest, RTSemRWRequestWrite(hSemRW, RT_INDEFINITE_WAIT), VINF_SUCCESS);
370
371 RTTHREAD hThread;
372 RTTEST_CHECK_RC_RETV(g_hTest, RTThreadCreate(&hThread, Test2Thread, hSemRW, 0,
373 RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "test2"),
374 VINF_SUCCESS);
375 RTTEST_CHECK_RC(g_hTest, RTThreadWait(hThread, 15000, NULL), VINF_SUCCESS);
376 RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseWrite(hSemRW), VINF_SUCCESS);
377
378 RTTEST_CHECK_RC(g_hTest, RTSemRWDestroy(hSemRW), VINF_SUCCESS);
379}
380
381
382static bool Test1(void)
383{
384 RTTestSub(g_hTest, "Basics");
385
386 RTSEMRW hSemRW = NIL_RTSEMRW;
387 RTTEST_CHECK_RC_RET(g_hTest, RTSemRWCreate(&hSemRW), VINF_SUCCESS, false);
388 RTTEST_CHECK_RET(g_hTest, hSemRW != NIL_RTSEMRW, false);
389
390 RTTEST_CHECK_RC_RET(g_hTest, RTSemRWRequestRead(hSemRW, RT_INDEFINITE_WAIT), VINF_SUCCESS, false);
391 RTTEST_CHECK_RC_RET(g_hTest, RTSemRWReleaseRead(hSemRW), VINF_SUCCESS, false);
392
393 for (unsigned cMs = 0; cMs < 50; cMs++)
394 {
395 RTTEST_CHECK_RC_RET(g_hTest, RTSemRWRequestRead(hSemRW, cMs), VINF_SUCCESS, false);
396 RTTEST_CHECK_RC_RET(g_hTest, RTSemRWRequestRead(hSemRW, cMs), VINF_SUCCESS, false);
397 RTTEST_CHECK_RC_RET(g_hTest, RTSemRWReleaseRead(hSemRW), VINF_SUCCESS, false);
398 RTTEST_CHECK_RC_RET(g_hTest, RTSemRWReleaseRead(hSemRW), VINF_SUCCESS, false);
399 }
400
401 RTTEST_CHECK_RC_RET(g_hTest, RTSemRWRequestWrite(hSemRW, RT_INDEFINITE_WAIT), VINF_SUCCESS, false);
402 RTTEST_CHECK_RC_RET(g_hTest, RTSemRWReleaseWrite(hSemRW), VINF_SUCCESS, false);
403
404 RTTEST_CHECK_RC_RET(g_hTest, RTSemRWRequestWrite(hSemRW, RT_INDEFINITE_WAIT), VINF_SUCCESS, false);
405 RTTEST_CHECK_RC_RET(g_hTest, RTSemRWRequestRead(hSemRW, RT_INDEFINITE_WAIT), VINF_SUCCESS, false);
406 RTTEST_CHECK_RC_RET(g_hTest, RTSemRWReleaseRead(hSemRW), VINF_SUCCESS, false);
407 RTTEST_CHECK_RC_RET(g_hTest, RTSemRWReleaseWrite(hSemRW), VINF_SUCCESS, false);
408
409 for (unsigned cMs = 0; cMs < 50; cMs++)
410 {
411 RTTEST_CHECK_RC_RET(g_hTest, RTSemRWRequestWrite(hSemRW, cMs), VINF_SUCCESS, false);
412 RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriteRecursion(hSemRW) == 1, false);
413 RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriterReadRecursion(hSemRW) == 0, false);
414 RTTEST_CHECK_RET(g_hTest, RTSemRWIsWriteOwner(hSemRW) == true, false);
415
416 RTTEST_CHECK_RC_RET(g_hTest, RTSemRWRequestWrite(hSemRW, cMs), VINF_SUCCESS, false);
417 RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriteRecursion(hSemRW) == 2, false);
418 RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriterReadRecursion(hSemRW) == 0, false);
419 RTTEST_CHECK_RET(g_hTest, RTSemRWIsWriteOwner(hSemRW) == true, false);
420
421 RTTEST_CHECK_RC_RET(g_hTest, RTSemRWRequestRead(hSemRW, cMs), VINF_SUCCESS, false);
422 RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriteRecursion(hSemRW) == 2, false);
423 RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriterReadRecursion(hSemRW) == 1, false);
424 RTTEST_CHECK_RET(g_hTest, RTSemRWIsWriteOwner(hSemRW) == true, false);
425
426 RTTEST_CHECK_RC_RET(g_hTest, RTSemRWRequestWrite(hSemRW, cMs), VINF_SUCCESS, false);
427 RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriteRecursion(hSemRW) == 3, false);
428 RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriterReadRecursion(hSemRW) == 1, false);
429 RTTEST_CHECK_RET(g_hTest, RTSemRWIsWriteOwner(hSemRW) == true, false);
430
431 /* midway */
432
433 RTTEST_CHECK_RC_RET(g_hTest, RTSemRWReleaseWrite(hSemRW), VINF_SUCCESS, false);
434 RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriteRecursion(hSemRW) == 2, false);
435 RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriterReadRecursion(hSemRW) == 1, false);
436 RTTEST_CHECK_RET(g_hTest, RTSemRWIsWriteOwner(hSemRW) == true, false);
437
438 RTTEST_CHECK_RC_RET(g_hTest, RTSemRWReleaseRead(hSemRW), VINF_SUCCESS, false);
439 RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriteRecursion(hSemRW) == 2, false);
440 RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriterReadRecursion(hSemRW) == 0, false);
441 RTTEST_CHECK_RET(g_hTest, RTSemRWIsWriteOwner(hSemRW) == true, false);
442
443 RTTEST_CHECK_RC_RET(g_hTest, RTSemRWReleaseWrite(hSemRW), VINF_SUCCESS, false);
444 RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriteRecursion(hSemRW) == 1, false);
445 RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriterReadRecursion(hSemRW) == 0, false);
446 RTTEST_CHECK_RET(g_hTest, RTSemRWIsWriteOwner(hSemRW) == true, false);
447
448 RTTEST_CHECK_RC_RET(g_hTest, RTSemRWReleaseWrite(hSemRW), VINF_SUCCESS, false);
449 RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriteRecursion(hSemRW) == 0, false);
450 RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriterReadRecursion(hSemRW) == 0, false);
451 RTTEST_CHECK_RET(g_hTest, RTSemRWIsWriteOwner(hSemRW) == false, false);
452 }
453
454 RTTEST_CHECK_RC_RET(g_hTest, RTSemRWDestroy(hSemRW), VINF_SUCCESS, false);
455 RTTEST_CHECK_RC_RET(g_hTest, RTSemRWDestroy(NIL_RTSEMRW), VINF_SUCCESS, false);
456
457 return true;
458}
459
460int main(int argc, char **argv)
461{
462 int rc = RTTestInitAndCreate("tstRTSemRW", &g_hTest);
463 if (rc)
464 return 1;
465 RTTestBanner(g_hTest);
466
467 if (Test1())
468 {
469 if (argc == 1)
470 {
471 Test2();
472 Test3();
473
474 /* threads, seconds, writePercent, yield, quiet */
475 Test4( 1, 1, 0, true, false);
476 Test4( 1, 1, 1, true, false);
477 Test4( 1, 1, 5, true, false);
478 Test4( 2, 1, 3, true, false);
479 Test4( 10, 1, 5, true, false);
480 Test4( 10, 10, 10, false, false);
481
482 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "benchmarking...\n");
483 for (unsigned cThreads = 1; cThreads < 32; cThreads++)
484 Test4(cThreads, 2, 1, false, true);
485
486 /** @todo add a testcase where some stuff times out. */
487 }
488 else
489 {
490 /* threads, seconds, writePercent, yield, quiet */
491 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "benchmarking...\n");
492 Test4( 1, 3, 1, false, true);
493 Test4( 1, 3, 1, false, true);
494 Test4( 1, 3, 1, false, true);
495 Test4( 2, 3, 1, false, true);
496 Test4( 2, 3, 1, false, true);
497 Test4( 2, 3, 1, false, true);
498 Test4( 3, 3, 1, false, true);
499 Test4( 3, 3, 1, false, true);
500 Test4( 3, 3, 1, false, true);
501 }
502 }
503
504 return RTTestSummaryAndDestroy(g_hTest);
505}
506
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