VirtualBox

Changeset 9583 in vbox for trunk/src


Ignore:
Timestamp:
Jun 10, 2008 11:45:10 PM (17 years ago)
Author:
vboxsync
Message:

Some fixes and adjustments.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r0drv/nt/timer-r0drv-nt.cpp

    r9580 r9583  
    146146    if (KeGetCurrentIrql() < DISPATCH_LEVEL)
    147147        AssertMsg2("rtTimerNtOmniSlaveCallback: Irql=%d expected >=%d\n", KeGetCurrentIrql(), DISPATCH_LEVEL);
    148     RTCPUID iCpuSelf = RTMpCpuIdToSetIndex(RTMpCpuId());
     148    int iCpuSelf = RTMpCpuIdToSetIndex(RTMpCpuId());
    149149    if (pSubTimer - &pTimer->aSubTimers[0] != iCpuSelf)
    150150        AssertMsg2("rtTimerNtOmniSlaveCallback: iCpuSelf=%d pSubTimer=%p / %d\n", iCpuSelf, pSubTimer, pSubTimer - &pTimer->aSubTimers[0]);
     
    177177    PRTTIMERNTSUBTIMER pSubTimer = (PRTTIMERNTSUBTIMER)pvUser;
    178178    PRTTIMER pTimer = pSubTimer->pParent;
    179     RTCPUID iCpuSelf = RTMpCpuIdToSetIndex(RTMpCpuId());
     179    int iCpuSelf = RTMpCpuIdToSetIndex(RTMpCpuId());
    180180
    181181    AssertPtr(pTimer);
     
    196196        RTCPUSET    OnlineSet;
    197197        RTMpGetOnlineSet(&OnlineSet);
    198         for (RTCPUID iCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++)
     198        for (int iCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++)
    199199            if (    RTCpuSetIsMemberByIndex(&OnlineSet, iCpu)
    200200                &&  iCpuSelf != iCpu)
     
    235235
    236236    LARGE_INTEGER DueTime;
    237     DueTime.QuadPart = -(int64_t)(u64First / 10000); /* Relative, NT time. */
     237    DueTime.QuadPart = -(int64_t)(u64First / 100); /* Relative, NT time. */
    238238    if (DueTime.QuadPart)
    239239        DueTime.QuadPart = -1;
     
    245245
    246246
     247/**
     248 * Worker function that stops an active timer.
     249 *
     250 * Shared by RTTimerStop and RTTimerDestroy.
     251 *
     252 * @param   pTimer      The active timer.
     253 */
     254static 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
    247275RTDECL(int) RTTimerStop(PRTTIMER pTimer)
    248276{
    249 
    250277    /*
    251278     * Validate.
     
    258285
    259286    /*
    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);
    267290    return VINF_SUCCESS;
    268291}
     
    278301
    279302    /*
    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);
    282307    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);
    289309    RTMemFree(pTimer);
    290310
     
    344364         */
    345365        pTimer->idCpu = NIL_RTCPUID; /* */
    346         for (RTCPUID iCpu = 0; iCpu < cSubTimers; iCpu++)
     366        for (unsigned iCpu = 0; iCpu < cSubTimers; iCpu++)
    347367        {
    348368            pTimer->aSubTimers[iCpu].iTick = 0;
     
    358378                KeInitializeDpc(&pTimer->aSubTimers[iCpu].NtDpc, rtTimerNtOmniSlaveCallback, &pTimer->aSubTimers[iCpu]);
    359379            KeSetImportanceDpc(&pTimer->aSubTimers[iCpu].NtDpc, HighImportance);
    360             KeSetTargetProcessorDpc(&pTimer->aSubTimers[iCpu].NtDpc, RTMpCpuIdFromSetIndex(iCpu));
     380            KeSetTargetProcessorDpc(&pTimer->aSubTimers[iCpu].NtDpc, (int)RTMpCpuIdFromSetIndex(iCpu));
    361381        }
    362382        Assert(pTimer->idCpu != NIL_RTCPUID);
     
    374394        KeSetImportanceDpc(&pTimer->aSubTimers[0].NtDpc, HighImportance);
    375395        if (pTimer->fSpecificCpu)
    376             KeSetTargetProcessorDpc(&pTimer->aSubTimers[0].NtDpc, pTimer->idCpu);
     396            KeSetTargetProcessorDpc(&pTimer->aSubTimers[0].NtDpc, (int)pTimer->idCpu);
    377397    }
    378398
     
    384404RTDECL(uint32_t) RTTimerGetSystemGranularity(void)
    385405{
     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();
    386412    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);
    394420    ULONG ulResolution2 = g_pfnrtNtExSetTimerResolution(0 /*ignored*/, FALSE);
    395     AssertMsg(ulResolution1 == ulResolution2, ("%ld, %ld\n", ulResolution1, ulResolution2));
    396     return ulResolution2 * 10000; /* NT -> ns */
     421    AssertMsg(ulResolution1 == ulResolution2, ("%ld, %ld\n", ulResolution1, ulResolution2)); /* not supposed to change it! */
     422    return ulResolution2 * 100; /* NT -> ns */
    397423}
    398424
     
    403429        return VERR_NOT_SUPPORTED;
    404430
    405     ULONG ulGranted = g_pfnrtNtExSetTimerResolution(u32Request / 10000, TRUE);
     431    ULONG ulGranted = g_pfnrtNtExSetTimerResolution(u32Request / 100, TRUE);
    406432    if (pu32Granted)
    407433        *pu32Granted = ulGranted;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette