VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTCritSectRw.cpp@ 58291

Last change on this file since 58291 was 57358, checked in by vboxsync, 9 years ago

*: scm cleanup run.

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