Changeset 28472 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Apr 19, 2010 2:59:33 PM (15 years ago)
- Location:
- trunk/src/VBox/Runtime/testcase
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/testcase/tstRTR0SemMutex.cpp
r28462 r28472 35 35 36 36 #include <iprt/err.h> 37 #include <VBox/sup.h> 38 #include <iprt/string.h> 37 39 #include <iprt/time.h> 38 #include <iprt/string.h> 39 #include <VBox/sup.h> 40 #include <iprt/thread.h> 40 41 #include "tstRTR0SemMutex.h" 42 43 44 /******************************************************************************* 45 * Global Variables * 46 *******************************************************************************/ 47 /** The mutex used in test #2. */ 48 static RTSEMMUTEX g_hMtxTest2 = NIL_RTSEMMUTEX; 41 49 42 50 … … 53 61 uint64_t u64Arg, PSUPR0SERVICEREQHDR pReqHdr) 54 62 { 55 if (u64Arg)56 return VERR_INVALID_PARAMETER;57 63 if (!VALID_PTR(pReqHdr)) 58 64 return VERR_INVALID_PARAMETER; … … 74 80 } 75 81 82 /* 83 * Set up test timeout (when applicable). 84 */ 85 if (u64Arg > 120) 86 { 87 SET_ERROR1("Timeout is too large (max 120): %lld", u64Arg); 88 return VINF_SUCCESS; 89 } 90 uint64_t const StartTS = RTTimeSystemMilliTS(); 91 uint32_t const cMsMax = (uint32_t)u64Arg * 1000; 76 92 77 93 /* 78 94 * The big switch. 79 95 */ 80 RTSEMMUTEX hMtx;81 int rc;96 RTSEMMUTEX hMtx; 97 int rc; 82 98 switch (uOperation) 83 99 { … … 178 194 break; 179 195 196 case TSTRTR0SEMMUTEX_TEST2_SETUP: 197 case TSTRTR0SEMMUTEX_TEST3_SETUP: 198 case TSTRTR0SEMMUTEX_TEST4_SETUP: 199 rc = RTSemMutexCreate(&g_hMtxTest2); 200 CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexCreate"); 201 break; 202 203 case TSTRTR0SEMMUTEX_TEST2_DO: 204 for (unsigned i = 0; i < 200; i++) 205 { 206 if (i & 1) 207 { 208 rc = RTSemMutexRequestNoResume(g_hMtxTest2, RT_INDEFINITE_WAIT); 209 CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRequestNoResume(,indef_wait)"); 210 } 211 else 212 { 213 rc = RTSemMutexRequestNoResume(g_hMtxTest2, 30000); 214 CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRequestNoResume(,30000)"); 215 } 216 RTThreadSleep(1); 217 rc = RTSemMutexRelease(g_hMtxTest2); 218 CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRelease"); 219 220 if ((i % 16) == 15 && RTTimeSystemMilliTS() - StartTS >= cMsMax) 221 break; 222 } 223 break; 224 225 226 case TSTRTR0SEMMUTEX_TEST3_DO: 227 for (unsigned i = 0; i < 1000000; i++) 228 { 229 if (i & 1) 230 { 231 rc = RTSemMutexRequestNoResume(g_hMtxTest2, RT_INDEFINITE_WAIT); 232 CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRequestNoResume(,indef_wait)"); 233 } 234 else 235 { 236 rc = RTSemMutexRequestNoResume(g_hMtxTest2, 30000); 237 CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRequestNoResume(,30000)"); 238 } 239 rc = RTSemMutexRelease(g_hMtxTest2); 240 CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRelease"); 241 242 if ((i % 256) == 255 && RTTimeSystemMilliTS() - StartTS >= cMsMax) 243 break; 244 } 245 break; 246 247 case TSTRTR0SEMMUTEX_TEST4_DO: 248 for (unsigned i = 0; i < 1024; i++) 249 { 250 rc = RTSemMutexRequestNoResume(g_hMtxTest2, (i % 32)); 251 if (rc != VERR_TIMEOUT) 252 { 253 CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRequestNoResume"); 254 RTThreadSleep(1000); 255 256 rc = RTSemMutexRelease(g_hMtxTest2); 257 CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRelease"); 258 } 259 260 if (RTTimeSystemMilliTS() - StartTS >= cMsMax) 261 break; 262 } 263 break; 264 265 case TSTRTR0SEMMUTEX_TEST2_CLEANUP: 266 case TSTRTR0SEMMUTEX_TEST3_CLEANUP: 267 case TSTRTR0SEMMUTEX_TEST4_CLEANUP: 268 rc = RTSemMutexDestroy(g_hMtxTest2); 269 CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexCreate"); 270 g_hMtxTest2 = NIL_RTSEMMUTEX; 271 break; 272 273 180 274 default: 181 275 SET_ERROR1("Unknown test #%d", uOperation); -
trunk/src/VBox/Runtime/testcase/tstRTR0SemMutex.h
r28462 r28472 40 40 TSTRTR0SEMMUTEX_SANITY_OK = 1, 41 41 TSTRTR0SEMMUTEX_SANITY_FAILURE, 42 TSTRTR0SEMMUTEX_BASIC 42 TSTRTR0SEMMUTEX_BASIC, 43 TSTRTR0SEMMUTEX_TEST2_SETUP, 44 TSTRTR0SEMMUTEX_TEST2_DO, 45 TSTRTR0SEMMUTEX_TEST2_CLEANUP, 46 TSTRTR0SEMMUTEX_TEST3_SETUP, 47 TSTRTR0SEMMUTEX_TEST3_DO, 48 TSTRTR0SEMMUTEX_TEST3_CLEANUP, 49 TSTRTR0SEMMUTEX_TEST4_SETUP, 50 TSTRTR0SEMMUTEX_TEST4_DO, 51 TSTRTR0SEMMUTEX_TEST4_CLEANUP 43 52 } TSTRTR0SEMMUTEX; 44 53 -
trunk/src/VBox/Runtime/testcase/tstRTR0SemMutexDriver.cpp
r28462 r28472 46 46 #endif 47 47 48 /******************************************************************************* 49 * Structures and Typedefs * 50 *******************************************************************************/ 51 typedef struct TSTRTR0SEMMUTEXREQ 52 { 53 SUPR0SERVICEREQHDR Hdr; 54 char szMsg[256]; 55 } TSTRTR0SEMMUTEXREQ; 56 typedef TSTRTR0SEMMUTEXREQ *PTSTRTR0SEMMUTEXREQ; 57 58 59 /******************************************************************************* 60 * Global Variables * 61 *******************************************************************************/ 62 static RTTEST g_hTest; 63 64 65 /** 66 * Thread function employed by tstDoThreadedTest. 67 * 68 * @returns IPRT status code. 69 * @param hThreadSelf The thread. 70 * @param pvUser The operation to perform. 71 */ 72 static DECLCALLBACK(int) tstThreadFn(RTTHREAD hThreadSelf, void *pvUser) 73 { 74 uint32_t u32 = (uint32_t)(uintptr_t)pvUser; 75 TSTRTR0SEMMUTEX enmDo = (TSTRTR0SEMMUTEX)RT_LOWORD(u32); 76 uint32_t cSecs = RT_HIWORD(u32); 77 TSTRTR0SEMMUTEXREQ Req; 78 RT_ZERO(Req); 79 Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC; 80 Req.Hdr.cbReq = sizeof(Req); 81 Req.szMsg[0] = '\0'; 82 RTTEST_CHECK_RC_RET(g_hTest, SUPR3CallR0Service("tstRTR0SemMutex", sizeof("tstRTR0SemMutex") - 1, 83 enmDo, cSecs, &Req.Hdr), 84 VINF_SUCCESS, 85 rcCheck); 86 return VINF_SUCCESS; 87 } 88 89 /** 90 * Performs a threaded test. 91 * 92 * @returns true on succes, false on failure. 93 * @param enmSetup The setup operation number. 94 * @param enmDo The do-it operation number. 95 * @param enmCleanup The cleanup operation number. 96 * @param cThreads The number of threads. 97 * @param pReq The request structure. 98 * @param pszTest The test name. 99 */ 100 static bool tstDoThreadedTest(TSTRTR0SEMMUTEX enmSetup, TSTRTR0SEMMUTEX enmDo, TSTRTR0SEMMUTEX enmCleanup, 101 unsigned cThreads, unsigned cSecs, PTSTRTR0SEMMUTEXREQ pReq, const char *pszTest) 102 { 103 RTTestSubF(g_hTest, "%s - %u threads", pszTest, cThreads); 104 RTTHREAD ahThreads[32]; 105 RTTESTI_CHECK_RET(cThreads <= RT_ELEMENTS(ahThreads), false); 106 107 /* 108 * Setup. 109 */ 110 pReq->Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC; 111 pReq->Hdr.cbReq = sizeof(*pReq); 112 pReq->szMsg[0] = '\0'; 113 RTTESTI_CHECK_RC_RET(SUPR3CallR0Service("tstRTR0SemMutex", sizeof("tstRTR0SemMutex") - 1, enmSetup, 0, &pReq->Hdr), 114 VINF_SUCCESS, false); 115 if (pReq->szMsg[0] == '!') 116 return RTTestIFailedRc(false, "%s", &pReq->szMsg[1]); 117 if (pReq->szMsg[0]) 118 RTTestIPrintf(RTTESTLVL_ALWAYS, "%s", pReq->szMsg); 119 120 /* 121 * Test execution. 122 */ 123 for (unsigned i = 0; i < RT_ELEMENTS(ahThreads); i++) 124 ahThreads[i] = NIL_RTTHREAD; 125 126 int rc = VINF_SUCCESS; 127 for (unsigned i = 0; i < cThreads && RT_SUCCESS(rc); i++) 128 rc = RTThreadCreateF(&ahThreads[i], tstThreadFn, (void *)(uintptr_t)RT_MAKE_U32(enmDo, cSecs), 0, RTTHREADTYPE_DEFAULT, 129 RTTHREADFLAGS_WAITABLE, "test-%u", i); 130 131 for (unsigned i = 0; i < cThreads; i++) 132 if (ahThreads[i] != NIL_RTTHREAD) 133 { 134 int rcThread = VINF_SUCCESS; 135 int rc2 = RTThreadWait(ahThreads[i], 3600*1000, &rcThread); 136 if (RT_SUCCESS(rc2)) 137 { 138 ahThreads[i] = NIL_RTTHREAD; 139 if (RT_FAILURE(rcThread) && RT_SUCCESS(rc2)) 140 rc = rcThread; 141 } 142 else if (RT_SUCCESS(rc)) 143 rc = rc2; 144 } 145 146 /* 147 * Cleanup. 148 */ 149 pReq->Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC; 150 pReq->Hdr.cbReq = sizeof(*pReq); 151 pReq->szMsg[0] = '\0'; 152 RTTESTI_CHECK_RC_RET(rc = SUPR3CallR0Service("tstRTR0SemMutex", sizeof("tstRTR0SemMutex") - 1, enmCleanup, 0, &pReq->Hdr), 153 VINF_SUCCESS, false); 154 if (pReq->szMsg[0] == '!') 155 return RTTestIFailedRc(false, "%s", &pReq->szMsg[1]); 156 if (pReq->szMsg[0]) 157 RTTestIPrintf(RTTESTLVL_ALWAYS, "%s", pReq->szMsg); 158 159 if (RT_FAILURE(rc)) 160 for (unsigned i = 0; i < cThreads; i++) 161 if (ahThreads[i] != NIL_RTTHREAD) 162 RTThreadWait(ahThreads[i], 1000, NULL); 163 164 return RT_SUCCESS(rc); 165 } 166 48 167 49 168 int main(int argc, char **argv) … … 57 176 */ 58 177 RTTEST hTest; 59 int rc = RTTestInitAndCreate("tstR 0SemMutex", &hTest);178 int rc = RTTestInitAndCreate("tstRTR0SemMutex", &hTest); 60 179 if (rc) 61 180 return rc; … … 73 192 rc = RTPathExecDir(szPath, sizeof(szPath)); 74 193 if (RT_SUCCESS(rc)) 75 rc = RTPathAppend(szPath, sizeof(szPath), "tstR 0SemMutex.r0");194 rc = RTPathAppend(szPath, sizeof(szPath), "tstRTR0SemMutex.r0"); 76 195 if (RT_FAILURE(rc)) 77 196 { … … 81 200 82 201 void *pvImageBase; 83 rc = SUPR3LoadServiceModule(szPath, "tstR 0SemMutex",202 rc = SUPR3LoadServiceModule(szPath, "tstRTR0SemMutex", 84 203 "TSTRTR0SemMutexSrvReqHandler", 85 204 &pvImageBase); … … 91 210 92 211 /* test request */ 93 struct 94 { 95 SUPR0SERVICEREQHDR Hdr; 96 char szMsg[256]; 97 } Req; 212 TSTRTR0SEMMUTEXREQ Req; 98 213 99 214 /* … … 104 219 Req.Hdr.cbReq = sizeof(Req); 105 220 Req.szMsg[0] = '\0'; 106 RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstR 0SemMutex", sizeof("tstR0SemMutex") - 1,221 RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstRTR0SemMutex", sizeof("tstRTR0SemMutex") - 1, 107 222 TSTRTR0SEMMUTEX_SANITY_OK, 0, &Req.Hdr), VINF_SUCCESS); 108 223 if (RT_FAILURE(rc)) … … 115 230 Req.Hdr.cbReq = sizeof(Req); 116 231 Req.szMsg[0] = '\0'; 117 RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstR 0SemMutex", sizeof("tstR0SemMutex") - 1,232 RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstRTR0SemMutex", sizeof("tstRTR0SemMutex") - 1, 118 233 TSTRTR0SEMMUTEX_SANITY_FAILURE, 0, &Req.Hdr), VINF_SUCCESS); 119 234 if (RT_FAILURE(rc)) … … 130 245 Req.Hdr.cbReq = sizeof(Req); 131 246 Req.szMsg[0] = '\0'; 132 RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstR 0SemMutex", sizeof("tstR0SemMutex") - 1,247 RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstRTR0SemMutex", sizeof("tstRTR0SemMutex") - 1, 133 248 TSTRTR0SEMMUTEX_BASIC, 0, &Req.Hdr), VINF_SUCCESS); 134 249 if (RT_FAILURE(rc)) … … 143 258 144 259 /* 145 * More to come 146 */ 260 * Tests with multiple threads for bugs in the contention part of the code. 261 * Test #2: Try to hold the semaphore for 1 ms. 262 * Test #3: Grab and release immediately. 263 * Test #4: Timeout checks. Try grab it for 0-32 ms and hold it for 1 s. 264 */ 265 tstDoThreadedTest(TSTRTR0SEMMUTEX_TEST2_SETUP, TSTRTR0SEMMUTEX_TEST2_DO, TSTRTR0SEMMUTEX_TEST2_CLEANUP, 1, 1, &Req, "test #2"); 266 tstDoThreadedTest(TSTRTR0SEMMUTEX_TEST2_SETUP, TSTRTR0SEMMUTEX_TEST2_DO, TSTRTR0SEMMUTEX_TEST2_CLEANUP, 2, 3, &Req, "test #2"); 267 tstDoThreadedTest(TSTRTR0SEMMUTEX_TEST2_SETUP, TSTRTR0SEMMUTEX_TEST2_DO, TSTRTR0SEMMUTEX_TEST2_CLEANUP, 3, 3, &Req, "test #2"); 268 tstDoThreadedTest(TSTRTR0SEMMUTEX_TEST2_SETUP, TSTRTR0SEMMUTEX_TEST2_DO, TSTRTR0SEMMUTEX_TEST2_CLEANUP, 9, 3, &Req, "test #2"); 269 270 tstDoThreadedTest(TSTRTR0SEMMUTEX_TEST3_SETUP, TSTRTR0SEMMUTEX_TEST3_DO, TSTRTR0SEMMUTEX_TEST3_CLEANUP, 1, 1, &Req, "test #3"); 271 tstDoThreadedTest(TSTRTR0SEMMUTEX_TEST3_SETUP, TSTRTR0SEMMUTEX_TEST3_DO, TSTRTR0SEMMUTEX_TEST3_CLEANUP, 2, 3, &Req, "test #3"); 272 tstDoThreadedTest(TSTRTR0SEMMUTEX_TEST3_SETUP, TSTRTR0SEMMUTEX_TEST3_DO, TSTRTR0SEMMUTEX_TEST3_CLEANUP, 3, 3, &Req, "test #3"); 273 tstDoThreadedTest(TSTRTR0SEMMUTEX_TEST3_SETUP, TSTRTR0SEMMUTEX_TEST3_DO, TSTRTR0SEMMUTEX_TEST3_CLEANUP, 9, 3, &Req, "test #3"); 274 275 tstDoThreadedTest(TSTRTR0SEMMUTEX_TEST4_SETUP, TSTRTR0SEMMUTEX_TEST4_DO, TSTRTR0SEMMUTEX_TEST4_CLEANUP, 1, 1, &Req, "test #4"); 276 tstDoThreadedTest(TSTRTR0SEMMUTEX_TEST4_SETUP, TSTRTR0SEMMUTEX_TEST4_DO, TSTRTR0SEMMUTEX_TEST4_CLEANUP, 2, 3, &Req, "test #4"); 277 tstDoThreadedTest(TSTRTR0SEMMUTEX_TEST4_SETUP, TSTRTR0SEMMUTEX_TEST4_DO, TSTRTR0SEMMUTEX_TEST4_CLEANUP, 3, 3, &Req, "test #4"); 278 tstDoThreadedTest(TSTRTR0SEMMUTEX_TEST4_SETUP, TSTRTR0SEMMUTEX_TEST4_DO, TSTRTR0SEMMUTEX_TEST4_CLEANUP, 9, 3, &Req, "test #4"); 147 279 148 280 /*
Note:
See TracChangeset
for help on using the changeset viewer.