- Timestamp:
- Jun 10, 2008 11:45:10 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r0drv/nt/timer-r0drv-nt.cpp
r9580 r9583 146 146 if (KeGetCurrentIrql() < DISPATCH_LEVEL) 147 147 AssertMsg2("rtTimerNtOmniSlaveCallback: Irql=%d expected >=%d\n", KeGetCurrentIrql(), DISPATCH_LEVEL); 148 RTCPUIDiCpuSelf = RTMpCpuIdToSetIndex(RTMpCpuId());148 int iCpuSelf = RTMpCpuIdToSetIndex(RTMpCpuId()); 149 149 if (pSubTimer - &pTimer->aSubTimers[0] != iCpuSelf) 150 150 AssertMsg2("rtTimerNtOmniSlaveCallback: iCpuSelf=%d pSubTimer=%p / %d\n", iCpuSelf, pSubTimer, pSubTimer - &pTimer->aSubTimers[0]); … … 177 177 PRTTIMERNTSUBTIMER pSubTimer = (PRTTIMERNTSUBTIMER)pvUser; 178 178 PRTTIMER pTimer = pSubTimer->pParent; 179 RTCPUIDiCpuSelf = RTMpCpuIdToSetIndex(RTMpCpuId());179 int iCpuSelf = RTMpCpuIdToSetIndex(RTMpCpuId()); 180 180 181 181 AssertPtr(pTimer); … … 196 196 RTCPUSET OnlineSet; 197 197 RTMpGetOnlineSet(&OnlineSet); 198 for ( RTCPUIDiCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++)198 for (int iCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++) 199 199 if ( RTCpuSetIsMemberByIndex(&OnlineSet, iCpu) 200 200 && iCpuSelf != iCpu) … … 235 235 236 236 LARGE_INTEGER DueTime; 237 DueTime.QuadPart = -(int64_t)(u64First / 100 00); /* Relative, NT time. */237 DueTime.QuadPart = -(int64_t)(u64First / 100); /* Relative, NT time. */ 238 238 if (DueTime.QuadPart) 239 239 DueTime.QuadPart = -1; … … 245 245 246 246 247 /** 248 * Worker function that stops an active timer. 249 * 250 * Shared by RTTimerStop and RTTimerDestroy. 251 * 252 * @param pTimer The active timer. 253 */ 254 static void rtTimerNtStopWorker(PRTTIMER pTimer) 255 { 256 /* 257 * Just cancel the timer, dequeue the DPCs and flush them (if this is supported). 258 */ 259 ASMAtomicWriteBool(&pTimer->fSuspended, true); 260 KeCancelTimer(&pTimer->NtTimer); 261 262 for (RTCPUID iCpu = 0; iCpu < pTimer->cSubTimers; iCpu++) 263 KeRemoveQueueDpc(&pTimer->aSubTimers[iCpu].NtDpc); 264 265 /* 266 * I'm a bit uncertain whether this should be done during RTTimerStop 267 * or only in RTTimerDestroy()... Linux and Solaris will wait AFAIK, 268 * which is why I'm keeping this here for now. 269 */ 270 if (g_pfnrtNtKeFlushQueuedDpcs) 271 g_pfnrtNtKeFlushQueuedDpcs(); 272 } 273 274 247 275 RTDECL(int) RTTimerStop(PRTTIMER pTimer) 248 276 { 249 250 277 /* 251 278 * Validate. … … 258 285 259 286 /* 260 * Just cancel the timer and flush DPCs. 261 */ 262 ASMAtomicWriteBool(&pTimer->fSuspended, true); 263 KeCancelTimer(&pTimer->NtTimer); 264 if (g_pfnrtNtKeFlushQueuedDpcs) 265 g_pfnrtNtKeFlushQueuedDpcs(); 266 287 * Call the worker we share with RTTimerDestroy. 288 */ 289 rtTimerNtStopWorker(pTimer); 267 290 return VINF_SUCCESS; 268 291 } … … 278 301 279 302 /* 280 * Stop the timer if it's running. 281 */ 303 * Invalidate the timer, stop it if it's running and finally . 304 * free up the memory. 305 */ 306 ASMAtomicWriteU32(&pTimer->u32Magic, ~RTTIMER_MAGIC); 282 307 if (!ASMAtomicUoReadBool(&pTimer->fSuspended)) 283 RTTimerStop(pTimer); 284 285 /* 286 * Uninitialize the structure and free the associated resources. 287 */ 288 ASMAtomicWriteU32(&pTimer->u32Magic, ~RTTIMER_MAGIC); 308 rtTimerNtStopWorker(pTimer); 289 309 RTMemFree(pTimer); 290 310 … … 344 364 */ 345 365 pTimer->idCpu = NIL_RTCPUID; /* */ 346 for ( RTCPUIDiCpu = 0; iCpu < cSubTimers; iCpu++)366 for (unsigned iCpu = 0; iCpu < cSubTimers; iCpu++) 347 367 { 348 368 pTimer->aSubTimers[iCpu].iTick = 0; … … 358 378 KeInitializeDpc(&pTimer->aSubTimers[iCpu].NtDpc, rtTimerNtOmniSlaveCallback, &pTimer->aSubTimers[iCpu]); 359 379 KeSetImportanceDpc(&pTimer->aSubTimers[iCpu].NtDpc, HighImportance); 360 KeSetTargetProcessorDpc(&pTimer->aSubTimers[iCpu].NtDpc, RTMpCpuIdFromSetIndex(iCpu));380 KeSetTargetProcessorDpc(&pTimer->aSubTimers[iCpu].NtDpc, (int)RTMpCpuIdFromSetIndex(iCpu)); 361 381 } 362 382 Assert(pTimer->idCpu != NIL_RTCPUID); … … 374 394 KeSetImportanceDpc(&pTimer->aSubTimers[0].NtDpc, HighImportance); 375 395 if (pTimer->fSpecificCpu) 376 KeSetTargetProcessorDpc(&pTimer->aSubTimers[0].NtDpc, pTimer->idCpu);396 KeSetTargetProcessorDpc(&pTimer->aSubTimers[0].NtDpc, (int)pTimer->idCpu); 377 397 } 378 398 … … 384 404 RTDECL(uint32_t) RTTimerGetSystemGranularity(void) 385 405 { 406 /* 407 * Get the default/max timer increment value, return it if ExtSetTimerResolution 408 * isn't available. Accoring to the sysinternals guys NtQueryTimerResolution 409 * is only available in userland and they find it equally annoying. 410 */ 411 ULONG ulTimeInc = KeQueryTimeIncrement(); 386 412 if (!g_pfnrtNtExSetTimerResolution) 387 return 156250; /* AMD64 default, will hopefully work for x86 too... */388 389 /* 390 * First try set it to the AMD64 default (which is higher than the default than x86)391 * and then restore it immediately. Wonder if this really works...392 */ 393 ULONG ulResolution1 = g_pfnrtNtExSetTimerResolution( 156250, TRUE);413 return ulTimeInc * 100; /* The value is in 100ns, the funny NT unit. */ 414 415 /* 416 * Use the value returned by ExSetTimerResolution. Since the kernel is keeping 417 * count of these calls, we have to do two calls that cancel each other out. 418 */ 419 ULONG ulResolution1 = g_pfnrtNtExSetTimerResolution(ulTimeInc, TRUE); 394 420 ULONG ulResolution2 = g_pfnrtNtExSetTimerResolution(0 /*ignored*/, FALSE); 395 AssertMsg(ulResolution1 == ulResolution2, ("%ld, %ld\n", ulResolution1, ulResolution2)); 396 return ulResolution2 * 100 00; /* NT -> ns */421 AssertMsg(ulResolution1 == ulResolution2, ("%ld, %ld\n", ulResolution1, ulResolution2)); /* not supposed to change it! */ 422 return ulResolution2 * 100; /* NT -> ns */ 397 423 } 398 424 … … 403 429 return VERR_NOT_SUPPORTED; 404 430 405 ULONG ulGranted = g_pfnrtNtExSetTimerResolution(u32Request / 100 00, TRUE);431 ULONG ulGranted = g_pfnrtNtExSetTimerResolution(u32Request / 100, TRUE); 406 432 if (pu32Granted) 407 433 *pu32Granted = ulGranted;
Note:
See TracChangeset
for help on using the changeset viewer.