Changeset 80665 in vbox for trunk/src/VBox
- Timestamp:
- Sep 9, 2019 10:43:23 AM (5 years ago)
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 2 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/generic/timerlr-generic.cpp
r76553 r80665 47 47 48 48 /********************************************************************************************************************************* 49 * Defined Constants And Macros * 50 *********************************************************************************************************************************/ 51 /** The smallest interval for low resolution timers. */ 52 #define RTTIMERLR_MIN_INTERVAL RT_NS_100MS 53 54 55 /********************************************************************************************************************************* 49 56 * Structures and Typedefs * 50 57 *********************************************************************************************************************************/ … … 62 69 /** Flag indicating that the timer has been destroyed. */ 63 70 bool volatile fDestroyed; 71 /** Set when the thread is blocked. */ 72 bool volatile fBlocked; 73 bool fPadding; 74 /** The timer interval. 0 if one-shot. */ 75 uint64_t volatile u64NanoInterval; 76 /** The start of the current run (ns). 77 * This is used to calculate when the timer ought to fire the next time. */ 78 uint64_t volatile u64StartTS; 79 /** The start of the current run (ns). 80 * This is used to calculate when the timer ought to fire the next time. */ 81 uint64_t volatile u64NextTS; 82 /** The current tick number (since u64StartTS). */ 83 uint64_t volatile iTick; 84 64 85 /** Callback. */ 65 86 PFNRTTIMERLR pfnTimer; … … 70 91 /** Event semaphore on which the thread is blocked. */ 71 92 RTSEMEVENT hEvent; 72 /** The timer interval. 0 if one-shot. */73 uint64_t u64NanoInterval;74 /** The start of the current run (ns).75 * This is used to calculate when the timer ought to fire the next time. */76 uint64_t volatile u64StartTS;77 /** The start of the current run (ns).78 * This is used to calculate when the timer ought to fire the next time. */79 uint64_t volatile u64NextTS;80 /** The current tick number (since u64StartTS). */81 uint64_t volatile iTick;82 93 } RTTIMERLRINT; 83 94 typedef RTTIMERLRINT *PRTTIMERLRINT; … … 98 109 * We don't support the fancy MP features, nor intervals lower than 100 ms. 99 110 */ 100 if (fFlags & RTTIMER_FLAGS_CPU_SPECIFIC) 101 return VERR_NOT_SUPPORTED; 102 if (u64NanoInterval && u64NanoInterval < 100*1000*1000) 103 return VERR_INVALID_PARAMETER; 111 AssertReturn(!(fFlags & RTTIMER_FLAGS_CPU_SPECIFIC), VERR_NOT_SUPPORTED); 112 AssertReturn(!u64NanoInterval || u64NanoInterval >= RTTIMERLR_MIN_INTERVAL, VERR_OUT_OF_RANGE); 104 113 105 114 /* … … 113 122 pThis->fSuspended = true; 114 123 pThis->fDestroyed = false; 124 pThis->fBlocked = false; 125 pThis->fPadding = false; 115 126 pThis->pfnTimer = pfnTimer; 116 127 pThis->pvUser = pvUser; … … 173 184 174 185 175 RTDECL(int) RTTimerLRStart(RTTIMERLR hTimerLR, uint64_t u64First) 176 { 177 /* 178 * Validate input. 179 */ 180 PRTTIMERLRINT pThis = hTimerLR; 181 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 182 AssertReturn(pThis->u32Magic == RTTIMERLR_MAGIC, VERR_INVALID_HANDLE); 183 AssertReturn(!pThis->fDestroyed, VERR_INVALID_HANDLE); 184 185 if (u64First && u64First < 100*1000*1000) 186 return VERR_INVALID_PARAMETER; 187 186 /** 187 * Internal worker fro RTTimerLRStart and RTTiemrLRChangeInterval. 188 */ 189 static int rtTimerLRStart(PRTTIMERLRINT pThis, uint64_t u64First) 190 { 188 191 if (!pThis->fSuspended) 189 192 return VERR_TIMER_ACTIVE; … … 203 206 return rc; 204 207 } 205 RT_EXPORT_SYMBOL(RTTimerLRStart); 206 207 208 RTDECL(int) RTTimerLRStop(RTTIMERLR hTimerLR) 208 209 210 RTDECL(int) RTTimerLRStart(RTTIMERLR hTimerLR, uint64_t u64First) 209 211 { 210 212 /* … … 215 217 AssertReturn(pThis->u32Magic == RTTIMERLR_MAGIC, VERR_INVALID_HANDLE); 216 218 AssertReturn(!pThis->fDestroyed, VERR_INVALID_HANDLE); 217 219 AssertReturn(!u64First || u64First >= RTTIMERLR_MIN_INTERVAL, VERR_OUT_OF_RANGE); 220 221 /* 222 * Do the job. 223 */ 224 return rtTimerLRStart(pThis, u64First); 225 } 226 RT_EXPORT_SYMBOL(RTTimerLRStart); 227 228 229 /** 230 * Internal worker for RTTimerLRStop and RTTimerLRChangeInterval 231 */ 232 static int rtTimerLRStop(PRTTIMERLRINT pThis, bool fSynchronous) 233 { 234 /* 235 * Fail if already suspended. 236 */ 218 237 if (pThis->fSuspended) 219 238 return VERR_TIMER_SUSPENDED; … … 221 240 /* 222 241 * Mark it as suspended and kick the thread. 223 */ 242 * It's simpler to always reset the thread user semaphore, so we do that first. 243 */ 244 int rc = RTThreadUserReset(pThis->hThread); 245 AssertRC(rc); 246 224 247 ASMAtomicWriteBool(&pThis->fSuspended, true); 225 intrc = RTSemEventSignal(pThis->hEvent);248 rc = RTSemEventSignal(pThis->hEvent); 226 249 if (rc == VERR_ALREADY_POSTED) 227 250 rc = VINF_SUCCESS; 228 251 AssertRC(rc); 252 253 /* 254 * Wait for the thread to stop running if synchronous. 255 */ 256 if (fSynchronous && RT_SUCCESS(rc)) 257 { 258 rc = RTThreadUserWait(pThis->hThread, RT_MS_1MIN); 259 AssertRC(rc); 260 } 261 229 262 return rc; 230 263 } 231 RT_EXPORT_SYMBOL(RTTimerLRStop); 232 233 RTDECL(int) RTTimerLRChangeInterval(RTTIMERLR hTimerLR, uint64_t u64NanoInterval) 234 { 264 265 266 RTDECL(int) RTTimerLRStop(RTTIMERLR hTimerLR) 267 { 268 /* 269 * Validate input. 270 */ 235 271 PRTTIMERLRINT pThis = hTimerLR; 236 272 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); … … 238 274 AssertReturn(!pThis->fDestroyed, VERR_INVALID_HANDLE); 239 275 240 if (u64NanoInterval && u64NanoInterval < 100*1000*1000) 241 return VERR_INVALID_PARAMETER; 242 243 #if 0 244 if (!pThis->fSuspended) 245 { 246 int rc = RTTimerLRStop(hTimerLR); 247 if (RT_FAILURE(rc)) 248 return rc; 249 276 /* 277 * Do the job. 278 */ 279 return rtTimerLRStop(pThis, false); 280 } 281 RT_EXPORT_SYMBOL(RTTimerLRStop); 282 283 284 RTDECL(int) RTTimerLRChangeInterval(RTTIMERLR hTimerLR, uint64_t u64NanoInterval) 285 { 286 /* 287 * Validate input. 288 */ 289 PRTTIMERLRINT pThis = hTimerLR; 290 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 291 AssertReturn(pThis->u32Magic == RTTIMERLR_MAGIC, VERR_INVALID_HANDLE); 292 AssertReturn(!pThis->fDestroyed, VERR_INVALID_HANDLE); 293 AssertReturn(!u64NanoInterval || u64NanoInterval >= RTTIMERLR_MIN_INTERVAL, VERR_OUT_OF_RANGE); 294 295 /* 296 * Do the job accoring to state and caller. 297 */ 298 int rc; 299 if (pThis->fSuspended) 300 { 301 /* Stopped: Just update the interval. */ 250 302 ASMAtomicWriteU64(&pThis->u64NanoInterval, u64NanoInterval); 251 252 rc = RTTimerLRStart(hTimerLR, 0); 253 if (RT_FAILURE(rc)) 254 return rc; 303 rc = VINF_SUCCESS; 304 } 305 else if (RTThreadSelf() == pThis->hThread) 306 { 307 /* Running: Updating interval from the callback. */ 308 uint64_t u64Now = RTTimeNanoTS(); 309 pThis->iTick = 0; 310 pThis->u64StartTS = u64Now; 311 pThis->u64NextTS = u64Now; 312 ASMAtomicWriteU64(&pThis->u64NanoInterval, u64NanoInterval); 313 rc = VINF_SUCCESS; 255 314 } 256 315 else 257 #endif 258 {259 uint64_t u64Now = RTTimeNanoTS();260 ASMAtomicWriteU64(&pThis->iTick, 0);261 ASMAtomicWriteU64(&pThis->u64StartTS, u64Now);262 ASMAtomicWriteU64(&pThis->u64NextTS, u64Now);263 ASMAtomicWriteU64(&pThis->u64NanoInterval, u64NanoInterval);264 RTSemEventSignal(pThis->hEvent);265 } 266 267 return VINF_SUCCESS;316 { 317 /* Running: Stopping */ 318 rc = rtTimerLRStop(pThis, true); 319 if (RT_SUCCESS(rc)) 320 { 321 ASMAtomicWriteU64(&pThis->u64NanoInterval, u64NanoInterval); 322 rc = rtTimerLRStart(pThis, 0); 323 } 324 } 325 326 return rc; 268 327 } 269 328 RT_EXPORT_SYMBOL(RTTimerLRChangeInterval); 329 270 330 271 331 static DECLCALLBACK(int) rtTimerLRThread(RTTHREAD hThreadSelf, void *pvUser) … … 281 341 if (ASMAtomicUoReadBool(&pThis->fSuspended)) 282 342 { 283 int rc = RTSemEventWait(pThis->hEvent, RT_INDEFINITE_WAIT); 343 /* Signal rtTimerLRStop thread. */ 344 int rc = RTThreadUserSignal(hThreadSelf); 345 AssertRC(rc); 346 347 ASMAtomicWriteBool(&pThis->fBlocked, true); 348 rc = RTSemEventWait(pThis->hEvent, RT_INDEFINITE_WAIT); 284 349 if (RT_FAILURE(rc) && rc != VERR_INTERRUPTED) 285 350 { … … 287 352 RTThreadSleep(1000); /* Don't cause trouble! */ 288 353 } 354 ASMAtomicWriteBool(&pThis->fBlocked, false); 289 355 } 290 356 else … … 292 358 uint64_t cNanoSeconds; 293 359 const uint64_t u64NanoTS = RTTimeNanoTS(); 294 if (u64NanoTS >= pThis->u64NextTS) 360 uint64_t u64NextTS = pThis->u64NextTS; 361 if (u64NanoTS >= u64NextTS) 295 362 { 296 pThis->iTick++;297 pThis->pfnTimer(pThis, pThis->pvUser, pThis->iTick);363 uint64_t iTick = ++pThis->iTick; 364 pThis->pfnTimer(pThis, pThis->pvUser, iTick); 298 365 299 366 /* status changed? */ 300 if ( 301 || 367 if ( ASMAtomicUoReadBool(&pThis->fSuspended) 368 || ASMAtomicUoReadBool(&pThis->fDestroyed)) 302 369 continue; 303 370 304 /* one shot? */ 305 if (!pThis->u64NanoInterval) 371 /* 372 * Read timer data (it's all volatile and better if we read it all at once): 373 */ 374 iTick = pThis->iTick; 375 uint64_t const u64StartTS = pThis->u64StartTS; 376 uint64_t const u64NanoInterval = pThis->u64NanoInterval; 377 ASMCompilerBarrier(); 378 379 /* 380 * Suspend if one shot. 381 */ 382 if (!u64NanoInterval) 306 383 { 307 384 ASMAtomicWriteBool(&pThis->fSuspended, true); … … 318 395 * if we're using a non-monotonic clock as time source. 319 396 */ 320 pThis->u64NextTS = pThis->u64StartTS + pThis->iTick * pThis->u64NanoInterval;321 if (RT_LIKELY( pThis->u64NextTS > u64NanoTS))322 cNanoSeconds = pThis->u64NextTS - u64NanoTS;397 u64NextTS = u64StartTS + iTick * u64NanoInterval; 398 if (RT_LIKELY(u64NextTS > u64NanoTS)) 399 cNanoSeconds = u64NextTS - u64NanoTS; 323 400 else 324 401 { 325 uint64_t iActualTick = (u64NanoTS - pThis->u64StartTS) / pThis->u64NanoInterval;326 if (iActualTick - pThis->iTick > 60)402 uint64_t iActualTick = (u64NanoTS - u64StartTS) / u64NanoInterval; 403 if (iActualTick - iTick > 60) 327 404 pThis->iTick = iActualTick - 1; 328 405 #ifdef IN_RING0 329 406 cNanoSeconds = RTTimerGetSystemGranularity() / 2; 330 407 #else 331 cNanoSeconds = 1000000; /* 1ms */408 cNanoSeconds = RT_NS_1MS; 332 409 #endif 333 pThis->u64NextTS = u64NanoTS + cNanoSeconds;410 u64NextTS = u64NanoTS + cNanoSeconds; 334 411 } 412 413 pThis->u64NextTS = u64NextTS; 335 414 } 336 415 else 337 cNanoSeconds = pThis->u64NextTS - u64NanoTS;416 cNanoSeconds = u64NextTS - u64NanoTS; 338 417 339 418 /* block. */ 419 ASMAtomicWriteBool(&pThis->fBlocked, true); 340 420 int rc = RTSemEventWait(pThis->hEvent, 341 421 (RTMSINTERVAL)(cNanoSeconds < 1000000 ? 1 : cNanoSeconds / 1000000)); … … 345 425 RTThreadSleep(1000); /* Don't cause trouble! */ 346 426 } 427 ASMAtomicWriteBool(&pThis->fBlocked, false); 347 428 } 348 429 } -
trunk/src/VBox/Runtime/testcase/Makefile.kmk
r80585 r80665 141 141 tstTime-4 \ 142 142 tstTimer \ 143 tst TimerLR \143 tstRTTimerLR \ 144 144 tstRTTimeSpec \ 145 145 tstRTUdp-1 \ … … 698 698 tstTimer_SOURCES = tstTimer.cpp 699 699 700 tst TimerLR_TEMPLATE = VBOXR3TSTEXE701 tst TimerLR_SOURCES = tstTimerLR.cpp700 tstRTTimerLR_TEMPLATE = VBOXR3TSTEXE 701 tstRTTimerLR_SOURCES = tstRTTimerLR.cpp 702 702 703 703 tstRTTimeSpec_TEMPLATE = VBOXR3TSTEXE -
trunk/src/VBox/Runtime/testcase/tstRTTimerLR.cpp
r80664 r80665 30 30 *********************************************************************************************************************************/ 31 31 #include <iprt/timer.h> 32 #include <iprt/time.h> 33 #include <iprt/thread.h> 34 #include <iprt/initterm.h> 32 33 #include <iprt/errcore.h> 35 34 #include <iprt/message.h> 36 35 #include <iprt/stream.h> 37 #include <iprt/errcore.h> 38 36 #include <iprt/test.h> 37 #include <iprt/thread.h> 38 #include <iprt/time.h> 39 39 40 40 … … 46 46 static volatile uint64_t gu64Max; 47 47 static volatile uint64_t gu64Prev; 48 48 49 49 50 static DECLCALLBACK(void) TimerLRCallback(RTTIMERLR hTimerLR, void *pvUser, uint64_t iTick) … … 71 72 * Init runtime 72 73 */ 73 unsigned cErrors = 0;74 int rc = RTR3InitExeNoArguments(0);75 if ( RT_FAILURE(rc))76 return RTMsgInitFailure(rc);74 RTTEST hTest; 75 RTEXITCODE rcExit = RTTestInitAndCreate("tstRTTimerLR", &hTest); 76 if (rcExit != RTEXITCODE_SUCCESS) 77 return rcExit; 77 78 78 79 /* 79 80 * Check that the clock is reliable. 80 81 */ 81 RT Printf("tstTimer: TESTING - RTTimeNanoTS() for 2sec\n");82 RTTestSub(hTest, "RTTimeNanoTS() for 2sec"); 82 83 uint64_t uTSMillies = RTTimeMilliTS(); 83 84 uint64_t uTSBegin = RTTimeNanoTS(); … … 90 91 uint64_t uTS = RTTimeNanoTS(); 91 92 if (uTS < uTSLast) 92 { 93 RTPrintf("tstTimer: FAILURE - RTTimeNanoTS() is unreliable. uTS=%RU64 uTSLast=%RU64\n", uTS, uTSLast); 94 cErrors++; 95 } 96 if (++cIterations > (2*1000*1000*1000)) 97 { 98 RTPrintf("tstTimer: FAILURE - RTTimeNanoTS() is unreliable. cIterations=%RU64 uTS=%RU64 uTSBegin=%RU64\n", cIterations, uTS, uTSBegin); 99 return 1; 93 RTTestFailed(hTest, "RTTimeNanoTS() is unreliable. uTS=%RU64 uTSLast=%RU64", uTS, uTSLast); 94 if (++cIterations > 2*1000*1000*1000) 95 { 96 RTTestFailed(hTest, "RTTimeNanoTS() is unreliable. cIterations=%RU64 uTS=%RU64 uTSBegin=%RU64", 97 cIterations, uTS, uTSBegin); 98 return RTTestSummaryAndDestroy(hTest); 100 99 } 101 100 uTSLast = uTS; … … 104 103 uTSMillies = RTTimeMilliTS() - uTSMillies; 105 104 if (uTSMillies >= 2500 || uTSMillies <= 1500) 106 { 107 RTPrintf("tstTimer: FAILURE - uTSMillies=%RI64 uTSBegin=%RU64 uTSLast=%RU64 uTSDiff=%RU64\n", 108 uTSMillies, uTSBegin, uTSLast, uTSDiff); 109 cErrors++; 110 } 111 if (!cErrors) 112 RTPrintf("tstTimer: OK - RTTimeNanoTS()\n"); 105 RTTestFailed(hTest, "uTSMillies=%RI64 uTSBegin=%RU64 uTSLast=%RU64 uTSDiff=%RU64", 106 uTSMillies, uTSBegin, uTSLast, uTSDiff); 113 107 114 108 /* … … 128 122 }; 129 123 124 int rc; 130 125 unsigned i = 0; 131 126 for (i = 0; i < RT_ELEMENTS(aTests); i++) … … 134 129 //aTests[i].cUpper = (aTests[i].uMilliesWait + aTests[i].uMilliesWait / 10) / aTests[i].uMilliesInterval; 135 130 136 RTPrintf("\n" 137 "tstTimer: TESTING - %d ms interval, %d ms wait, expects %d-%d ticks.\n", 138 aTests[i].uMilliesInterval, aTests[i].uMilliesWait, aTests[i].cLower, aTests[i].cUpper); 131 RTTestSubF(hTest, "%d ms interval, %d ms wait, expects %d-%d ticks", 132 aTests[i].uMilliesInterval, aTests[i].uMilliesWait, aTests[i].cLower, aTests[i].cUpper); 139 133 140 134 /* … … 149 143 if (RT_FAILURE(rc)) 150 144 { 151 RTPrintf("RTTimerLRCreateEX(,%u*1M,,,) -> %d\n", aTests[i].uMilliesInterval, rc); 152 cErrors++; 145 RTTestFailed(hTest, "RTTimerLRCreateEX(,%u*1M,,,) -> %Rrc", aTests[i].uMilliesInterval, rc); 153 146 continue; 154 147 } … … 160 153 rc = RTTimerLRStart(hTimerLR, 0); 161 154 if (RT_FAILURE(rc)) 162 { 163 RTPrintf("tstTimer: FAILURE - RTTimerLRStart() -> %Rrc\n", rc); 164 cErrors++; 165 } 155 RTTestFailed(hTest, "RTTimerLRStart() -> %Rrc", rc); 166 156 167 157 while (RTTimeNanoTS() - uTSBegin < (uint64_t)aTests[i].uMilliesWait * 1000000) 168 /* nothing */;158 RTThreadSleep(1); 169 159 170 160 /* don't stop it, destroy it because there are potential races in destroying an active timer. */ 171 161 rc = RTTimerLRDestroy(hTimerLR); 172 162 if (RT_FAILURE(rc)) 173 { 174 RTPrintf("tstTimer: FAILURE - RTTimerLRDestroy() -> %d gcTicks=%d\n", rc, gcTicks); 175 cErrors++; 176 } 163 RTTestFailed(hTest, "RTTimerLRDestroy() -> %Rrc gcTicks=%d", rc, gcTicks); 177 164 178 165 uint64_t uTSEnd = RTTimeNanoTS(); 179 166 uTSDiff = uTSEnd - uTSBegin; 180 RTPrintf("uTS=%RI64 (%RU64 - %RU64)\n", uTSDiff, uTSBegin, uTSEnd); 167 RTTestPrintf(hTest, RTTESTLVL_ALWAYS, "uTS=%'RI64 (%'RU64 - %'RU64) gcTicks=%u min=%'RU64 max=%'RU64\n", 168 uTSDiff, uTSBegin, uTSEnd, gcTicks, gu64Min, gu64Max); 181 169 182 170 /* Check that it really stopped. */ … … 185 173 if (gcTicks != cTicks) 186 174 { 187 RTPrintf("tstTimer: FAILURE - RTTimerLRDestroy() didn't really stop the timer! gcTicks=%d cTicks=%d\n", gcTicks, cTicks); 188 cErrors++; 175 RTTestFailed(hTest, "RTTimerLRDestroy() didn't really stop the timer! gcTicks=%d cTicks=%d", gcTicks, cTicks); 189 176 continue; 190 177 } … … 194 181 */ 195 182 if (gcTicks < aTests[i].cLower) 196 { 197 RTPrintf("tstTimer: FAILURE - Too few ticks gcTicks=%d (expected %d-%d)", gcTicks, aTests[i].cUpper, aTests[i].cLower); 198 cErrors++; 199 } 183 RTTestFailed(hTest, "Too few ticks gcTicks=%d (expected %d-%d)", gcTicks, aTests[i].cUpper, aTests[i].cLower); 200 184 else if (gcTicks > aTests[i].cUpper) 201 { 202 RTPrintf("tstTimer: FAILURE - Too many ticks gcTicks=%d (expected %d-%d)", gcTicks, aTests[i].cUpper, aTests[i].cLower); 203 cErrors++; 204 } 205 else 206 RTPrintf("tstTimer: OK - gcTicks=%d", gcTicks); 207 RTPrintf(" min=%RU64 max=%RU64\n", gu64Min, gu64Max); 185 RTTestFailed(hTest, "Too many ticks gcTicks=%d (expected %d-%d)", gcTicks, aTests[i].cUpper, aTests[i].cLower); 208 186 } 209 187 … … 211 189 * Test changing the interval dynamically 212 190 */ 213 RTPrintf("\n" 214 "tstTimer: Testing dynamic changes of timer interval...\n"); 191 RTTestSub(hTest, "RTTimerLRChangeInterval"); 215 192 do 216 193 { … … 219 196 if (RT_FAILURE(rc)) 220 197 { 221 RTPrintf("RTTimerLRCreateEX(,%u*1M,,,) -> %d\n", aTests[0].uMilliesInterval, rc); 222 cErrors++; 223 continue; 198 RTTestFailed(hTest, "RTTimerLRCreateEX(,%u*1M,,,) -> %Rrc", aTests[0].uMilliesInterval, rc); 199 break; 224 200 } 225 201 226 202 for (i = 0; i < RT_ELEMENTS(aTests); i++) 227 203 { 228 RTPrintf("\n" 229 "tstTimer: TESTING - %d ms interval, %d ms wait, expects %d-%d ticks.\n", 230 aTests[i].uMilliesInterval, aTests[i].uMilliesWait, aTests[i].cLower, aTests[i].cUpper); 204 RTTestPrintf(hTest, RTTESTLVL_ALWAYS, "%d ms interval, %d ms wait, expects %d-%d ticks.\n", 205 aTests[i].uMilliesInterval, aTests[i].uMilliesWait, aTests[i].cLower, aTests[i].cUpper); 231 206 232 207 gcTicks = 0; … … 234 209 gu64Min = UINT64_MAX; 235 210 gu64Prev = 0; 211 236 212 /* 237 213 * Start the timer an actively wait for it for the period requested. … … 242 218 rc = RTTimerLRStart(hTimerLR, 0); 243 219 if (RT_FAILURE(rc)) 244 { 245 RTPrintf("tstTimer: FAILURE - RTTimerLRStart() -> %Rrc\n", rc); 246 cErrors++; 247 } 220 RTTestFailed(hTest, "RTTimerLRStart() -> %Rrc", rc); 248 221 } 249 222 else 250 223 { 251 rc = RTTimerLRChangeInterval(hTimerLR, aTests[i].uMilliesInterval * (uint64_t)1000000);224 rc = RTTimerLRChangeInterval(hTimerLR, aTests[i].uMilliesInterval * RT_NS_1MS_64); 252 225 if (RT_FAILURE(rc)) 253 { 254 RTPrintf("tstTimer: FAILURE - RTTimerLRChangeInterval() -> %d gcTicks=%d\n", rc, gcTicks); 255 cErrors++; 256 } 226 RTTestFailed(hTest, "RTTimerLRChangeInterval() -> %d gcTicks=%d", rc, gcTicks); 257 227 } 258 228 259 while (RTTimeNanoTS() - uTSBegin < (uint64_t)aTests[i].uMilliesWait * 1000000)260 /* nothing */;229 while (RTTimeNanoTS() - uTSBegin < (uint64_t)aTests[i].uMilliesWait * RT_NS_1MS_64) 230 RTThreadSleep(1); 261 231 262 232 uint64_t uTSEnd = RTTimeNanoTS(); 263 233 uTSDiff = uTSEnd - uTSBegin; 264 RTPrintf("uTS=%RI64 (%RU64 - %RU64)\n", uTSDiff, uTSBegin, uTSEnd); 234 RTTestPrintf(hTest, RTTESTLVL_ALWAYS, "uTS=%'RI64 (%'RU64 - %'RU64) gcTicks=%u min=%'RU64 max=%'RU64\n", 235 uTSDiff, uTSBegin, uTSEnd, gcTicks, gu64Min, gu64Max); 265 236 266 237 /* … … 268 239 */ 269 240 if (gcTicks < aTests[i].cLower) 270 { 271 RTPrintf("tstTimer: FAILURE - Too few ticks gcTicks=%d (expected %d-%d)\n", gcTicks, aTests[i].cUpper, aTests[i].cLower); 272 cErrors++; 273 } 241 RTTestFailed(hTest, "Too few ticks gcTicks=%d (expected %d-%d)", gcTicks, aTests[i].cUpper, aTests[i].cLower); 274 242 else if (gcTicks > aTests[i].cUpper) 275 { 276 RTPrintf("tstTimer: FAILURE - Too many ticks gcTicks=%d (expected %d-%d)\n", gcTicks, aTests[i].cUpper, aTests[i].cLower); 277 cErrors++; 278 } 279 else 280 RTPrintf("tstTimer: OK - gcTicks=%d\n", gcTicks); 281 // RTPrintf(" min=%RU64 max=%RU64\n", gu64Min, gu64Max); 282 } 243 RTTestFailed(hTest, "Too many ticks gcTicks=%d (expected %d-%d)", gcTicks, aTests[i].cUpper, aTests[i].cLower); 244 } 245 283 246 /* don't stop it, destroy it because there are potential races in destroying an active timer. */ 284 247 rc = RTTimerLRDestroy(hTimerLR); 285 248 if (RT_FAILURE(rc)) 286 { 287 RTPrintf("tstTimer: FAILURE - RTTimerLRDestroy() -> %d gcTicks=%d\n", rc, gcTicks); 288 cErrors++; 289 } 249 RTTestFailed(hTest, "RTTimerLRDestroy() -> %d gcTicks=%d", rc, gcTicks); 290 250 } while (0); 291 251 … … 298 258 * Summary. 299 259 */ 300 if (!cErrors) 301 RTPrintf("tstTimer: SUCCESS\n"); 302 else 303 RTPrintf("tstTimer: FAILURE %d errors\n", cErrors); 304 return !!cErrors; 260 return RTTestSummaryAndDestroy(hTest); 305 261 } 306 262
Note:
See TracChangeset
for help on using the changeset viewer.