- Timestamp:
- Jun 9, 2009 3:00:20 PM (16 years ago)
- Location:
- trunk/src/VBox/Runtime/testcase
- Files:
-
- 1 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/testcase/Makefile.kmk
r20111 r20443 114 114 tstInlineAsmPIC \ 115 115 tstInlineAsmPIC3 \ 116 tstSemMutex 116 tstSemMutex \ 117 tstSemRW 117 118 PROGRAMS.l4 += \ 118 119 tstIoCtl … … 337 338 tstSemMutex_SOURCES = tstSemMutex.cpp 338 339 340 tstSemRW_SOURCES = tstSemRW.cpp 341 339 342 tstSemPingPong_SOURCES = tstSemPingPong.cpp 340 343 -
trunk/src/VBox/Runtime/testcase/tstSemRW.cpp
r20412 r20443 1 1 /* $Id$ */ 2 2 /** @file 3 * IPRT Testcase - Simple Semaphore Smoke Test.3 * IPRT Testcase - Reader/Writer Semaphore Test. 4 4 */ 5 5 6 6 /* 7 * Copyright (C) 200 6-2007Sun Microsystems, Inc.7 * Copyright (C) 2009 Sun Microsystems, Inc. 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 38 38 #include <iprt/time.h> 39 39 #include <iprt/initterm.h> 40 #include <iprt/rand.h> 40 41 #include <iprt/asm.h> 41 42 #include <iprt/assert.h> … … 45 46 * Global Variables * 46 47 *******************************************************************************/ 47 static RTSEM MUTEX g_hMutex = NIL_RTSEMMUTEX;48 static RTSEMRW g_hSemRW = NIL_RTSEMRW; 48 49 static bool volatile g_fTerminate; 49 50 static bool g_fYield; 50 51 static bool g_fQuiet; 51 static uint32_t volatile g_cbConcurrent; 52 static unsigned g_uWritePercent; 53 static uint32_t volatile g_cbConcurrentWrite; 54 static uint32_t volatile g_cbConcurrentRead; 52 55 static uint32_t volatile g_cErrors; 53 56 … … 57 60 ASMAtomicIncU32(&g_cErrors); 58 61 59 RTPrintf("tstSem Mutex: FAILURE - ");62 RTPrintf("tstSemRW: FAILURE - "); 60 63 va_list va; 61 64 va_start(va, pszFormat); … … 69 72 int ThreadTest1(RTTHREAD ThreadSelf, void *pvUser) 70 73 { 74 // Use randomization to get a little more variation of the sync pattern 75 unsigned c100 = RTRandU32Ex(0, 99); 71 76 uint64_t *pu64 = (uint64_t *)pvUser; 77 bool fWrite; 72 78 for (;;) 73 79 { 74 int rc = RTSemMutexRequestNoResume(g_hMutex, RT_INDEFINITE_WAIT); 75 if (RT_FAILURE(rc)) 80 int rc; 81 fWrite = (c100 < g_uWritePercent); 82 if (fWrite) 76 83 { 77 PrintError("%x: RTSemMutexRequestNoResume failed with %Rrc\n", rc); 78 break; 84 rc = RTSemRWRequestWriteNoResume(g_hSemRW, RT_INDEFINITE_WAIT); 85 if (RT_FAILURE(rc)) 86 { 87 PrintError("%x: RTSemRWRequestWriteNoResume failed with %Rrc\n", rc); 88 break; 89 } 90 if (ASMAtomicIncU32(&g_cbConcurrentWrite) != 1) 91 { 92 PrintError("g_cbConcurrentWrite=%d after request!\n", g_cbConcurrentWrite); 93 break; 94 } 95 if (g_cbConcurrentRead != 0) 96 { 97 PrintError("g_cbConcurrentRead=%d after request!\n", g_cbConcurrentRead); 98 break; 99 } 79 100 } 80 if (ASMAtomicIncU32(&g_cbConcurrent) != 1)101 else 81 102 { 82 PrintError("g_cbConcurrent=%d after request!\n", g_cbConcurrent); 83 break; 103 rc = RTSemRWRequestReadNoResume(g_hSemRW, RT_INDEFINITE_WAIT); 104 if (RT_FAILURE(rc)) 105 { 106 PrintError("%x: RTSemRWRequestReadNoResume failed with %Rrc\n", rc); 107 break; 108 } 109 ASMAtomicIncU32(&g_cbConcurrentRead); 110 if (g_cbConcurrentWrite != 0) 111 { 112 PrintError("g_cbConcurrentWrite=%d after request!\n", g_cbConcurrentWrite); 113 break; 114 } 84 115 } 85 116 … … 95 126 if (g_fYield) 96 127 RTThreadYield(); 97 if (ASMAtomicDecU32(&g_cbConcurrent) != 0) 128 129 if (fWrite) 98 130 { 99 PrintError("g_cbConcurrent=%d before release!\n", g_cbConcurrent); 100 break; 131 if (ASMAtomicDecU32(&g_cbConcurrentWrite) != 0) 132 { 133 PrintError("g_cbConcurrentWrite=%d before release!\n", g_cbConcurrentWrite); 134 break; 135 } 136 if (g_cbConcurrentRead != 0) 137 { 138 PrintError("g_cbConcurrentRead=%d before release!\n", g_cbConcurrentRead); 139 break; 140 } 141 rc = RTSemRWReleaseWrite(g_hSemRW); 142 if (RT_FAILURE(rc)) 143 { 144 PrintError("%x: RTSemRWReleaseWrite failed with %Rrc\n", rc); 145 break; 146 } 101 147 } 102 rc = RTSemMutexRelease(g_hMutex); 103 if (RT_FAILURE(rc)) 148 else 104 149 { 105 PrintError("%x: RTSemMutexRelease failed with %Rrc\n", rc); 106 break; 150 if (g_cbConcurrentWrite != 0) 151 { 152 PrintError("g_cbConcurrentWrite=%d before release!\n", g_cbConcurrentWrite); 153 break; 154 } 155 ASMAtomicDecU32(&g_cbConcurrentRead); 156 rc = RTSemRWReleaseRead(g_hSemRW); 157 if (RT_FAILURE(rc)) 158 { 159 PrintError("%x: RTSemRWReleaseRead failed with %Rrc\n", rc); 160 break; 161 } 107 162 } 163 108 164 if (g_fTerminate) 109 165 break; 166 167 c100++; 168 c100 %= 100; 110 169 } 111 170 if (!g_fQuiet) 112 RTPrintf("tstSem Mutex: Thread %08x exited with %lld\n", ThreadSelf, *pu64);171 RTPrintf("tstSemRW: Thread %08x exited with %lld\n", ThreadSelf, *pu64); 113 172 return VINF_SUCCESS; 114 173 } 115 174 116 175 117 static int Test1(unsigned cThreads, unsigned cSeconds, bool fYield, bool fQuiet)176 static int Test1(unsigned cThreads, unsigned cSeconds, unsigned uWritePercent, bool fYield, bool fQuiet) 118 177 { 119 178 int rc; … … 129 188 g_fQuiet = fQuiet; 130 189 g_fTerminate = false; 131 132 rc = RTSemMutexCreate(&g_hMutex); 133 if (RT_FAILURE(rc)) 134 return PrintError("RTSemMutexCreate failed (rc=%Rrc)\n", rc); 190 g_uWritePercent = uWritePercent; 191 g_cbConcurrentWrite = 0; 192 g_cbConcurrentRead = 0; 193 194 rc = RTSemRWCreate(&g_hSemRW); 195 if (RT_FAILURE(rc)) 196 return PrintError("RTSemRWCreate failed (rc=%Rrc)\n", rc); 135 197 136 198 /* 137 * Create the threads and let them block on the mutex.199 * Create the threads and let them block on the semrw. 138 200 */ 139 rc = RTSem MutexRequest(g_hMutex, RT_INDEFINITE_WAIT);140 if (RT_FAILURE(rc)) 141 return PrintError("RTSem MutexRequestfailed (rc=%Rrc)\n", rc);201 rc = RTSemRWRequestWrite(g_hSemRW, RT_INDEFINITE_WAIT); 202 if (RT_FAILURE(rc)) 203 return PrintError("RTSemRWRequestWrite failed (rc=%Rrc)\n", rc); 142 204 143 205 for (i = 0; i < cThreads; i++) … … 150 212 151 213 if (!fQuiet) 152 RTPrintf("tstSem Mutex: %zu Threads created. Racing them for %u seconds (%s) ...\n",214 RTPrintf("tstSemRW: %zu Threads created. Racing them for %u seconds (%s) ...\n", 153 215 cThreads, cSeconds, g_fYield ? "yielding" : "no yielding"); 154 216 155 217 uint64_t u64StartTS = RTTimeNanoTS(); 156 rc = RTSem MutexRelease(g_hMutex);157 if (RT_FAILURE(rc)) 158 PrintError("RTSem MutexRelease failed (rc=%Rrc)\n", rc);218 rc = RTSemRWReleaseWrite(g_hSemRW); 219 if (RT_FAILURE(rc)) 220 PrintError("RTSemRWReleaseWrite failed (rc=%Rrc)\n", rc); 159 221 RTThreadSleep(cSeconds * 1000); 160 222 ASMAtomicXchgBool(&g_fTerminate, true); … … 168 230 } 169 231 170 rc = RTSemMutexDestroy(g_hMutex); 171 if (RT_FAILURE(rc)) 172 PrintError("RTSemMutexDestroy failed - %Rrc\n", rc); 173 g_hMutex = NIL_RTSEMMUTEX; 232 if (g_cbConcurrentWrite != 0) 233 PrintError("g_cbConcurrentWrite=%d at end of test!\n", g_cbConcurrentWrite); 234 if (g_cbConcurrentRead != 0) 235 PrintError("g_cbConcurrentRead=%d at end of test!\n", g_cbConcurrentRead); 236 237 rc = RTSemRWDestroy(g_hSemRW); 238 if (RT_FAILURE(rc)) 239 PrintError("RTSemRWDestroy failed - %Rrc\n", rc); 240 g_hSemRW = NIL_RTSEMRW; 174 241 if (g_cErrors) 175 242 RTThreadSleep(100); … … 183 250 184 251 uint64_t Normal = Total / cThreads; 185 uint64_t MaxD iviation = 0;252 uint64_t MaxDeviation = 0; 186 253 for (i = 0; i < cThreads; i++) 187 254 { 188 255 uint64_t Delta = RT_ABS((int64_t)(g_au64[i] - Normal)); 189 256 if (Delta > Normal / 2) 190 RTPrintf("tstSem Mutex: Warning! Thread %d diviates by more than 50%% - %llu (it) vs. %llu (avg)\n",257 RTPrintf("tstSemRW: Warning! Thread %d deviates by more than 50%% - %llu (it) vs. %llu (avg)\n", 191 258 i, g_au64[i], Normal); 192 if (Delta > MaxD iviation)193 MaxD iviation = Delta;194 195 } 196 197 RTPrintf("tstSem Mutex: Threads: %u Total: %llu Per Sec: %llu Avg: %llu ns Max div: %llu%%\n",259 if (Delta > MaxDeviation) 260 MaxDeviation = Delta; 261 262 } 263 264 RTPrintf("tstSemRW: Threads: %u Total: %llu Per Sec: %llu Avg: %llu ns Max dev: %llu%%\n", 198 265 cThreads, 199 266 Total, 200 267 Total / cSeconds, 201 268 ElapsedNS / Total, 202 MaxD iviation * 100 / Normal269 MaxDeviation * 100 / Normal 203 270 ); 204 271 return 0; … … 211 278 if (RT_FAILURE(rc)) 212 279 { 213 RTPrintf("tstSem Mutex: RTR3Init failed (rc=%Rrc)\n", rc);280 RTPrintf("tstSemRW: RTR3Init failed (rc=%Rrc)\n", rc); 214 281 return 1; 215 282 } 216 RTPrintf("tstSem Mutex: TESTING...\n");283 RTPrintf("tstSemRW: TESTING...\n"); 217 284 218 285 if (argc == 1) 219 286 { 220 /* threads, seconds, yield, quiet */ 221 Test1( 1, 1, true, false); 222 Test1( 2, 1, true, false); 223 Test1( 10, 1, true, false); 224 Test1( 10, 10, false, false); 225 226 RTPrintf("tstSemMutex: benchmarking...\n"); 287 /* threads, seconds, writePercent, yield, quiet */ 288 Test1( 1, 1, 0, true, false); 289 Test1( 1, 1, 1, true, false); 290 Test1( 1, 1, 5, true, false); 291 Test1( 2, 1, 3, true, false); 292 Test1( 10, 1, 5, true, false); 293 Test1( 10, 10, 10, false, false); 294 295 RTPrintf("tstSemRW: benchmarking...\n"); 227 296 for (unsigned cThreads = 1; cThreads < 32; cThreads++) 228 Test1(cThreads, 2, false, true);297 Test1(cThreads, 2, 1, false, true); 229 298 230 299 /** @todo add a testcase where some stuff times out. */ … … 232 301 else 233 302 { 234 /* threads, seconds, yield, quiet */235 RTPrintf("tstSem Mutex: benchmarking...\n");236 Test1( 1, 3, false, true);237 Test1( 1, 3, false, true);238 Test1( 1, 3, false, true);239 Test1( 2, 3, false, true);240 Test1( 2, 3, false, true);241 Test1( 2, 3, false, true);242 Test1( 3, 3, false, true);243 Test1( 3, 3, false, true);244 Test1( 3, 3, false, true);303 /* threads, seconds, writePercent, yield, quiet */ 304 RTPrintf("tstSemRW: benchmarking...\n"); 305 Test1( 1, 3, 1, false, true); 306 Test1( 1, 3, 1, false, true); 307 Test1( 1, 3, 1, false, true); 308 Test1( 2, 3, 1, false, true); 309 Test1( 2, 3, 1, false, true); 310 Test1( 2, 3, 1, false, true); 311 Test1( 3, 3, 1, false, true); 312 Test1( 3, 3, 1, false, true); 313 Test1( 3, 3, 1, false, true); 245 314 } 246 315 247 316 if (!g_cErrors) 248 RTPrintf("tstSem Mutex: SUCCESS\n");317 RTPrintf("tstSemRW: SUCCESS\n"); 249 318 else 250 RTPrintf("tstSem Mutex: FAILURE - %u errors\n", g_cErrors);319 RTPrintf("tstSemRW: FAILURE - %u errors\n", g_cErrors); 251 320 return g_cErrors != 0; 252 321 }
Note:
See TracChangeset
for help on using the changeset viewer.