Changeset 32946 in vbox for trunk/src/VBox/Runtime/testcase/tstSemEvent.cpp
- Timestamp:
- Oct 6, 2010 2:21:29 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/testcase/tstSemEvent.cpp
r28800 r32946 25 25 */ 26 26 27 27 28 /******************************************************************************* 28 29 * Header Files * 29 30 *******************************************************************************/ 30 31 #include <iprt/semaphore.h> 31 #include <iprt/string.h> 32 #include <iprt/thread.h> 33 #include <iprt/stream.h> 34 #include <iprt/time.h> 35 #include <iprt/initterm.h> 36 #include <iprt/rand.h> 32 37 33 #include <iprt/asm.h> 38 34 #include <iprt/assert.h> 35 #include <iprt/rand.h> 36 #include <iprt/stream.h> 37 #include <iprt/string.h> 38 #include <iprt/test.h> 39 #include <iprt/thread.h> 40 #include <iprt/time.h> 39 41 40 42 … … 42 44 * Global Variables * 43 45 *******************************************************************************/ 44 static RTSEMEVENTMULTI g_hSemEM = NIL_RTSEMEVENTMULTI; 45 static uint32_t volatile g_cErrors; 46 47 48 int PrintError(const char *pszFormat, ...) 49 { 50 ASMAtomicIncU32(&g_cErrors); 51 52 RTPrintf("tstSemEvent: FAILURE - "); 53 va_list va; 54 va_start(va, pszFormat); 55 RTPrintfV(pszFormat, va); 56 va_end(va); 57 58 return 1; 59 } 60 61 62 int ThreadTest1(RTTHREAD ThreadSelf, void *pvUser) 63 { 64 int rc; 65 rc = RTSemEventMultiWait(g_hSemEM, 1000); 66 if (rc != VERR_TIMEOUT) 67 { 68 PrintError("Thread 1: unexpected result of first RTSemEventMultiWait %Rrc\n", rc); 69 return VINF_SUCCESS; 70 } 71 72 rc = RTSemEventMultiWait(g_hSemEM, 1000); 73 if (RT_FAILURE(rc)) 74 { 75 PrintError("Thread 1: unexpected result of second RTSemEventMultiWait %Rrc\n", rc); 76 return VINF_SUCCESS; 77 } 78 79 RTPrintf("tstSemEvent: Thread 1 normal exit...\n"); 46 /** The test handle. */ 47 static RTTEST g_hTest; 48 49 50 static DECLCALLBACK(int) test1Thread1(RTTHREAD ThreadSelf, void *pvUser) 51 { 52 RTSEMEVENTMULTI hSem = *(PRTSEMEVENTMULTI)pvUser; 53 54 uint64_t u64 = RTTimeSystemMilliTS(); 55 RTTEST_CHECK_RC_RET(g_hTest, RTSemEventMultiWait(hSem, 1000), VERR_TIMEOUT, rcCheck); 56 u64 = RTTimeSystemMilliTS() - u64; 57 RTTEST_CHECK_MSG(g_hTest, u64 < 1500 && u64 > 950, (g_hTest, "u64=%llu\n", u64)); 58 59 RTTEST_CHECK_RC_RET(g_hTest, RTSemEventMultiWait(hSem, 2000), VINF_SUCCESS, rcCheck); 80 60 return VINF_SUCCESS; 81 61 } 82 62 83 63 84 int ThreadTest2(RTTHREAD ThreadSelf, void *pvUser) 85 { 86 int rc; 87 rc = RTSemEventMultiWait(g_hSemEM, RT_INDEFINITE_WAIT); 88 if (RT_FAILURE(rc)) 89 { 90 PrintError("Thread 2: unexpected result of RTSemEventMultiWait %Rrc\n", rc); 91 return VINF_SUCCESS; 92 } 93 94 RTPrintf("tstSemEvent: Thread 2 normal exit...\n"); 64 static DECLCALLBACK(int) test1Thread2(RTTHREAD ThreadSelf, void *pvUser) 65 { 66 RTSEMEVENTMULTI hSem = *(PRTSEMEVENTMULTI)pvUser; 67 RTTEST_CHECK_RC_RET(g_hTest, RTSemEventMultiWait(hSem, RT_INDEFINITE_WAIT), VINF_SUCCESS, rcCheck); 95 68 return VINF_SUCCESS; 96 69 } 97 70 98 71 99 static int Test1() 100 { 101 int rc; 102 RTTHREAD Thread1, Thread2; 103 104 rc = RTSemEventMultiCreate(&g_hSemEM); 105 if (RT_FAILURE(rc)) 106 return PrintError("RTSemEventMultiCreate failed (rc=%Rrc)\n", rc); 72 static void test1(void) 73 { 74 RTTestISub("Three threads"); 107 75 108 76 /* 109 77 * Create the threads and let them block on the event multi semaphore. 110 78 */ 111 rc = RTSemEventMultiReset(g_hSemEM); 112 if (RT_FAILURE(rc)) 113 return PrintError("RTSemEventMultiReset failed (rc=%Rrc)\n", rc); 114 115 rc = RTThreadCreate(&Thread2, ThreadTest2, NULL, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "test2"); 116 if (RT_FAILURE(rc)) 117 return PrintError("RTThreadCreate failed for thread 2 (rc=%Rrc)\n", rc); 79 RTSEMEVENTMULTI hSem; 80 RTTESTI_CHECK_RC_RETV(RTSemEventMultiCreate(&hSem), VINF_SUCCESS); 81 82 RTTHREAD hThread2; 83 RTTESTI_CHECK_RC_RETV(RTThreadCreate(&hThread2, test1Thread2, &hSem, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "test2"), VINF_SUCCESS); 118 84 RTThreadSleep(100); 119 85 120 rc = RTThreadCreate(&Thread1, ThreadTest1, NULL, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "test1"); 121 if (RT_FAILURE(rc)) 122 return PrintError("RTThreadCreate failed for thread 1 (rc=%Rrc)\n", rc); 86 RTTHREAD hThread1; 87 RTTESTI_CHECK_RC_RETV(RTThreadCreate(&hThread1, test1Thread1, &hSem, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "test1"), VINF_SUCCESS); 123 88 124 89 /* Force first thread (which has a timeout of 1 second) to timeout in the 125 90 * first wait, and the second wait will succeed. */ 126 RTThreadSleep(1500); 127 rc = RTSemEventMultiSignal(g_hSemEM); 128 if (RT_FAILURE(rc)) 129 PrintError("RTSemEventMultiSignal failed (rc=%Rrc)\n", rc); 130 131 rc = RTThreadWait(Thread1, 5000, NULL); 132 if (RT_FAILURE(rc)) 133 PrintError("RTThreadWait failed for thread 1 (rc=%Rrc)\n", rc); 134 135 rc = RTThreadWait(Thread2, 5000, NULL); 136 if (RT_FAILURE(rc)) 137 PrintError("RTThreadWait failed for thread 2 (rc=%Rrc)\n", rc); 138 139 rc = RTSemEventMultiDestroy(g_hSemEM); 140 if (RT_FAILURE(rc)) 141 PrintError("RTSemEventMultiDestroy failed - %Rrc\n", rc); 142 g_hSemEM = NIL_RTSEMEVENTMULTI; 143 if (g_cErrors) 144 RTThreadSleep(100); 145 return 0; 91 RTTESTI_CHECK_RC(RTThreadSleep(1500), VINF_SUCCESS); 92 RTTESTI_CHECK_RC(RTSemEventMultiSignal(hSem), VINF_SUCCESS); 93 RTTESTI_CHECK_RC(RTThreadWait(hThread1, 5000, NULL), VINF_SUCCESS); 94 RTTESTI_CHECK_RC(RTThreadWait(hThread2, 5000, NULL), VINF_SUCCESS); 95 RTTESTI_CHECK_RC(RTSemEventMultiDestroy(hSem), VINF_SUCCESS); 96 } 97 98 99 static void testBasicsWaitTimeout(RTSEMEVENTMULTI hSem, unsigned i) 100 { 101 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWait(hSem, 0), VERR_TIMEOUT); 102 #if 1 103 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitNoResume(hSem, 0), VERR_TIMEOUT); 104 #else 105 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem, 106 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_RELATIVE, 107 0), 108 VERR_TIMEOUT); 109 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem, 110 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_ABSOLUTE, 111 RTTimeSystemNanoTS() + 1000*i), 112 VERR_TIMEOUT); 113 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem, 114 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_ABSOLUTE, 115 RTTimeNanoTS() + 1000*i), 116 VERR_TIMEOUT); 117 118 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem, 119 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_MILLISECS | RTSEMWAIT_FLAGS_RELATIVE, 120 0), 121 VERR_TIMEOUT); 122 #endif 123 } 124 125 126 static void testBasicsWaitSuccess(RTSEMEVENTMULTI hSem, unsigned i) 127 { 128 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWait(hSem, 0), VINF_SUCCESS); 129 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWait(hSem, RT_INDEFINITE_WAIT), VINF_SUCCESS); 130 #if 1 131 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitNoResume(hSem, 0), VINF_SUCCESS); 132 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitNoResume(hSem, RT_INDEFINITE_WAIT), VINF_SUCCESS); 133 #else 134 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem, 135 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_RELATIVE, 136 0), 137 VINF_SUCCESS); 138 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem, RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_INDEFINITE, 0), VINF_SUCCESS); 139 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem, RTSEMWAIT_FLAGS_NORESUME | RTSEMWAIT_FLAGS_INDEFINITE, 0), VINF_SUCCESS); 140 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem, 141 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_ABSOLUTE, 142 RTTimeSystemNanoTS() + 1000*i), 143 VINF_SUCCESS); 144 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem, 145 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_ABSOLUTE, 146 RTTimeNanoTS() + 1000*i), 147 VINF_SUCCESS); 148 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem, 149 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_ABSOLUTE, 150 0), 151 VINF_SUCCESS); 152 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem, 153 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_ABSOLUTE, 154 _1G), 155 VINF_SUCCESS); 156 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem, 157 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_ABSOLUTE, 158 UINT64_MAX), 159 VINF_SUCCESS); 160 161 162 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem, 163 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_MILLISECS | RTSEMWAIT_FLAGS_ABSOLUTE, 164 RTTimeSystemMilliTS() + 1000*i), 165 VINF_SUCCESS); 166 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem, 167 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_MILLISECS | RTSEMWAIT_FLAGS_ABSOLUTE, 168 RTTimeMilliTS() + 1000*i), 169 VINF_SUCCESS); 170 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem, 171 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_MILLISECS | RTSEMWAIT_FLAGS_ABSOLUTE, 172 0), 173 VINF_SUCCESS); 174 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem, 175 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_MILLISECS | RTSEMWAIT_FLAGS_ABSOLUTE, 176 _1M), 177 VINF_SUCCESS); 178 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem, 179 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_MILLISECS | RTSEMWAIT_FLAGS_ABSOLUTE, 180 UINT64_MAX), 181 VINF_SUCCESS); 182 #endif 183 } 184 185 186 static void testBasics(void) 187 { 188 RTTestISub("Basics"); 189 190 RTSEMEVENTMULTI hSem; 191 RTTESTI_CHECK_RC_RETV(RTSemEventMultiCreate(&hSem), VINF_SUCCESS); 192 193 /* The semaphore is created in a reset state, calling reset explicitly 194 shouldn't make any difference. */ 195 testBasicsWaitTimeout(hSem, 0); 196 RTTESTI_CHECK_RC_RETV(RTSemEventMultiReset(hSem), VINF_SUCCESS); 197 testBasicsWaitTimeout(hSem, 1); 198 if (RTTestIErrorCount()) 199 return; 200 201 /* When signalling the semaphore all successive wait calls shall 202 succeed, signalling it again should make no difference. */ 203 RTTESTI_CHECK_RC_RETV(RTSemEventMultiSignal(hSem), VINF_SUCCESS); 204 testBasicsWaitSuccess(hSem, 2); 205 if (RTTestIErrorCount()) 206 return; 207 208 /* After resetting it we should time out again. */ 209 RTTESTI_CHECK_RC_RETV(RTSemEventMultiReset(hSem), VINF_SUCCESS); 210 testBasicsWaitTimeout(hSem, 3); 211 if (RTTestIErrorCount()) 212 return; 213 214 /* The number of resets or signal calls shouldn't matter. */ 215 RTTESTI_CHECK_RC_RETV(RTSemEventMultiReset(hSem), VINF_SUCCESS); 216 RTTESTI_CHECK_RC_RETV(RTSemEventMultiReset(hSem), VINF_SUCCESS); 217 RTTESTI_CHECK_RC_RETV(RTSemEventMultiReset(hSem), VINF_SUCCESS); 218 testBasicsWaitTimeout(hSem, 4); 219 220 RTTESTI_CHECK_RC_RETV(RTSemEventMultiSignal(hSem), VINF_SUCCESS); 221 RTTESTI_CHECK_RC_RETV(RTSemEventMultiSignal(hSem), VINF_SUCCESS); 222 RTTESTI_CHECK_RC_RETV(RTSemEventMultiSignal(hSem), VINF_SUCCESS); 223 RTTESTI_CHECK_RC_RETV(RTSemEventMultiSignal(hSem), VINF_SUCCESS); 224 RTTESTI_CHECK_RC_RETV(RTSemEventMultiSignal(hSem), VINF_SUCCESS); 225 testBasicsWaitSuccess(hSem, 5); 226 227 RTTESTI_CHECK_RC_RETV(RTSemEventMultiReset(hSem), VINF_SUCCESS); 228 testBasicsWaitTimeout(hSem, 6); 229 230 /* Destroy it. */ 231 RTTESTI_CHECK_RC_RETV(RTSemEventMultiDestroy(hSem), VINF_SUCCESS); 232 RTTESTI_CHECK_RC_RETV(RTSemEventMultiDestroy(NIL_RTSEMEVENTMULTI), VINF_SUCCESS); 233 234 /* Whether it is reset (above), signalled or not used shouldn't matter. */ 235 RTTESTI_CHECK_RC_RETV(RTSemEventMultiCreate(&hSem), VINF_SUCCESS); 236 RTTESTI_CHECK_RC_RETV(RTSemEventMultiSignal(hSem), VINF_SUCCESS); 237 RTTESTI_CHECK_RC_RETV(RTSemEventMultiDestroy(hSem), VINF_SUCCESS); 238 239 RTTESTI_CHECK_RC_RETV(RTSemEventMultiCreate(&hSem), VINF_SUCCESS); 240 RTTESTI_CHECK_RC_RETV(RTSemEventMultiDestroy(hSem), VINF_SUCCESS); 241 242 RTTestISubDone(); 146 243 } 147 244 … … 149 246 int main(int argc, char **argv) 150 247 { 151 int rc = RTR3Init(); 152 if (RT_FAILURE(rc)) 248 RTEXITCODE rcExit = RTTestInitAndCreate("tstSemEventMulti", &g_hTest); 249 if (rcExit != RTEXITCODE_SUCCESS) 250 return rcExit; 251 252 testBasics(); 253 if (!RTTestErrorCount(g_hTest)) 153 254 { 154 RTPrintf("tstSemEvent: RTR3Init failed (rc=%Rrc)\n", rc); 155 return 1; 255 test1(); 156 256 } 157 RTPrintf("tstSemEvent: TESTING...\n"); 158 Test1(); 159 160 if (!g_cErrors) 161 RTPrintf("tstSemEvent: SUCCESS\n"); 162 else 163 RTPrintf("tstSemEvent: FAILURE - %u errors\n", g_cErrors); 164 return g_cErrors != 0; 165 } 166 257 258 return RTTestSummaryAndDestroy(g_hTest); 259 } 260
Note:
See TracChangeset
for help on using the changeset viewer.