VirtualBox

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

Last change on this file since 45733 was 45020, checked in by vboxsync, 12 years ago

tstRTSemRW/test4: Set a couple of values instead of using just printing them to stdout.

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