Changeset 6741 in vbox
- Timestamp:
- Feb 2, 2008 12:19:04 AM (17 years ago)
- svn:sync-xref-src-repo-rev:
- 27823
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/testcase/tstSemMutex.cpp
r6740 r6741 32 32 #include <iprt/thread.h> 33 33 #include <iprt/stream.h> 34 #include <iprt/time.h> 34 35 #include <iprt/initterm.h> 35 36 #include <iprt/asm.h> 36 37 #include <iprt/assert.h> 38 39 40 /******************************************************************************* 41 * Defined Constants And Macros * 42 *******************************************************************************/ 37 43 #define SECONDS 10 38 44 39 static RTSEMMUTEX g_mutex; 40 static uint64_t g_au64[10]; 41 static bool g_fTerminate; 42 static bool g_fYield = true; 43 static uint32_t g_cbConcurrent; 44 45 /******************************************************************************* 46 * Global Variables * 47 *******************************************************************************/ 48 static RTSEMMUTEX g_hMutex = NIL_RTSEMMUTEX; 49 static bool volatile g_fTerminate; 50 static bool g_fYield; 51 static bool g_fQuiet; 52 static uint32_t volatile g_cbConcurrent; 45 53 static uint32_t volatile g_cErrors; 46 54 … … 60 68 61 69 62 int ThreadTest (RTTHREAD ThreadSelf, void *pvUser)70 int ThreadTest1(RTTHREAD ThreadSelf, void *pvUser) 63 71 { 64 72 uint64_t *pu64 = (uint64_t *)pvUser; 65 73 for (;;) 66 74 { 67 int rc = RTSemMutexRequestNoResume(g_ mutex, RT_INDEFINITE_WAIT);75 int rc = RTSemMutexRequestNoResume(g_hMutex, RT_INDEFINITE_WAIT); 68 76 if (RT_FAILURE(rc)) 69 77 { … … 93 101 break; 94 102 } 95 rc = RTSemMutexRelease(g_ mutex);103 rc = RTSemMutexRelease(g_hMutex); 96 104 if (RT_FAILURE(rc)) 97 105 { … … 102 110 break; 103 111 } 104 RTPrintf("tstSemMutex: Thread %08x exited with %lld\n", ThreadSelf, *pu64); 112 if (!g_fQuiet) 113 RTPrintf("tstSemMutex: Thread %08x exited with %lld\n", ThreadSelf, *pu64); 105 114 return VINF_SUCCESS; 106 115 } 107 116 117 118 static int Test1(unsigned cThreads, unsigned cSeconds, bool fYield, bool fQuiet) 119 { 120 int rc; 121 unsigned i; 122 uint64_t g_au64[32]; 123 RTTHREAD aThreads[RT_ELEMENTS(g_au64)]; 124 AssertRelease(cThreads <= RT_ELEMENTS(g_au64)); 125 126 /* 127 * Init globals. 128 */ 129 g_fYield = fYield; 130 g_fQuiet = fQuiet; 131 g_fTerminate = false; 132 133 rc = RTSemMutexCreate(&g_hMutex); 134 if (RT_FAILURE(rc)) 135 return PrintError("RTSemMutexCreate failed (rc=%Rrc)\n", rc); 136 137 /* 138 * Create the threads and let them block on the mutex. 139 */ 140 rc = RTSemMutexRequest(g_hMutex, RT_INDEFINITE_WAIT); 141 if (RT_FAILURE(rc)) 142 return PrintError("RTSemMutexRequest failed (rc=%Rrc)\n", rc); 143 144 for (i = 0; i < cThreads; i++) 145 { 146 g_au64[i] = 0; 147 rc = RTThreadCreate(&aThreads[i], ThreadTest1, &g_au64[i], 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "test"); 148 if (RT_FAILURE(rc)) 149 return PrintError("RTThreadCreate failed for thread %u (rc=%Rrc)\n", i, rc); 150 } 151 152 if (!fQuiet) 153 RTPrintf("tstSemMutex: %zu Threads created. Racing them for %u seconds (%s) ...\n", 154 cThreads, SECONDS, g_fYield ? "yielding" : "no yielding"); 155 156 uint64_t u64StartTS = RTTimeNanoTS(); 157 rc = RTSemMutexRelease(g_hMutex); 158 if (RT_FAILURE(rc)) 159 PrintError("RTSemMutexRelease failed (rc=%Rrc)\n", rc); 160 RTThreadSleep(cSeconds * 1000); 161 ASMAtomicXchgBool(&g_fTerminate, true); 162 uint64_t ElapsedNS = RTTimeNanoTS() - u64StartTS; 163 164 for (i = 0; i < cThreads; i++) 165 { 166 rc = RTThreadWait(aThreads[i], 5000, NULL); 167 if (RT_FAILURE(rc)) 168 PrintError("RTThreadWait failed for thread %u (rc=%Rrc)\n", i, rc); 169 } 170 171 rc = RTSemMutexDestroy(g_hMutex); 172 if (RT_FAILURE(rc)) 173 PrintError("RTSemMutexDestroy failed - %Rrc\n", rc); 174 g_hMutex = NIL_RTSEMMUTEX; 175 if (g_cErrors) 176 RTThreadSleep(100); 177 178 /* 179 * Collect and display the results. 180 */ 181 uint64_t Total = g_au64[0]; 182 for (i = 1; i < cThreads; i++) 183 Total += g_au64[i]; 184 185 uint64_t Normal = Total / cThreads; 186 uint64_t MaxDiviation = 0; 187 for (i = 0; i < cThreads; i++) 188 { 189 uint64_t Delta = RT_ABS((int64_t)(g_au64[i] - Normal)); 190 if (Delta > Normal / 2) 191 RTPrintf("tstSemMutex: Warning! Thread %d diviates by more than 50%% - %llu (it) vs. %llu (avg)\n", 192 i, g_au64[i], Normal); 193 if (Delta > MaxDiviation) 194 MaxDiviation = Delta; 195 196 } 197 198 RTPrintf("tstSemMutex: Threads: %u Total: %llu Per Sec: %llu Avg: %llu ns Max div: %llu%%\n", 199 cThreads, 200 Total, 201 Total / cThreads, 202 ElapsedNS / Total, 203 MaxDiviation * 100 / Normal 204 ); 205 return 0; 206 } 207 208 108 209 int main() 109 210 { 110 int rc; 111 unsigned u; 112 RTTHREAD aThreads[RT_ELEMENTS(g_au64)]; 113 114 rc = RTR3Init(false, 0); 211 int rc = RTR3Init(false, 0); 115 212 if (RT_FAILURE(rc)) 116 213 { … … 118 215 return 1; 119 216 } 120 121 122 rc = RTSemMutexCreate(&g_mutex); 123 if (RT_FAILURE(rc)) 124 { 125 RTPrintf("tstSemMutex: RTSemMutexCreate failed (rc=%Rrc)\n", rc); 126 return 1; 127 } 128 for (u = 0; u < RT_ELEMENTS(g_au64); u++) 129 { 130 rc = RTThreadCreate(&aThreads[u], ThreadTest, &g_au64[u], 0, RTTHREADTYPE_DEFAULT, 0, "test"); 131 if (RT_FAILURE(rc)) 132 { 133 RTPrintf("tstSemMutex: RTThreadCreate failed for thread %u (rc=%Rrc)\n", u, rc); 134 return 1; 135 } 136 } 137 138 RTPrintf("tstSemMutex: %zu Threads created. Racing them for %u seconds (%s) ...\n", 139 RT_ELEMENTS(g_au64), SECONDS, g_fYield ? "yielding" : "no yielding"); 140 RTThreadSleep(SECONDS * 1000); 141 g_fTerminate = true; 142 RTThreadSleep(100); 143 RTSemMutexDestroy(g_mutex); 144 RTThreadSleep(100); 145 146 for (u = 1; u < RT_ELEMENTS(g_au64); u++) 147 g_au64[0] += g_au64[u]; 148 RTPrintf("tstSemMutex: Done. In total: %lld\n", g_au64[0]); 149 217 RTPrintf("tstSemMutex: TESTING...\n"); 218 219 /* threads, seconds, yield, quiet */ 220 Test1(1, 1, true, false); 221 Test1(2, 1, true, false); 222 Test1(10, 1, true, false); 223 Test1(10, 10, false, false); 224 225 RTPrintf("tstSemMutex: benchmarking... \n"); 226 for (unsigned cThreads = 1; cThreads < 32; cThreads++) 227 Test1(cThreads, 2, false, true); 150 228 151 229 if (!g_cErrors)
Note:
See TracChangeset
for help on using the changeset viewer.