VirtualBox

Ignore:
Timestamp:
Feb 23, 2015 8:50:46 PM (10 years ago)
Author:
vboxsync
Message:

Eliminated supdrvTscDeltaApply. corrected explanation in supdrvGipSyncAndInvariantTimer.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPDrvGip.cpp

    r54395 r54402  
    142142static DECLCALLBACK(void)   supdrvGipAsyncTimer(PRTTIMER pTimer, void *pvUser, uint64_t iTick);
    143143static void                 supdrvGipInitCpu(PSUPGLOBALINFOPAGE pGip, PSUPGIPCPU pCpu, uint64_t u64NanoTS, uint64_t uCpuHz);
    144 static int                  supdrvMeasureInitialTscDeltas(PSUPDRVDEVEXT pDevExt);
    145 static int                  supdrvMeasureTscDeltaOne(PSUPDRVDEVEXT pDevExt, uint32_t idxWorker);
    146144#ifdef SUPDRV_USE_TSC_DELTA_THREAD
    147145static int                  supdrvTscDeltaThreadInit(PSUPDRVDEVEXT pDevExt);
    148146static void                 supdrvTscDeltaTerm(PSUPDRVDEVEXT pDevExt);
    149147static void                 supdrvTscDeltaThreadStartMeasurement(PSUPDRVDEVEXT pDevExt);
     148#else
     149static int                  supdrvMeasureInitialTscDeltas(PSUPDRVDEVEXT pDevExt);
     150static int                  supdrvMeasureTscDeltaOne(PSUPDRVDEVEXT pDevExt, uint32_t idxWorker);
    150151#endif
    151152
     
    184185}
    185186
    186 
    187 /**
    188  * Applies the TSC delta to the supplied raw TSC value.
    189  *
    190  * @returns VBox status code. (Ignored by all users, just FYI.)
    191  * @param   pGip            Pointer to the GIP.
    192  * @param   puTsc           Pointer to a valid TSC value before the TSC delta has been applied.
    193  * @param   idApic          The APIC ID of the CPU @c puTsc corresponds to.
    194  * @param   fDeltaApplied   Where to store whether the TSC delta was succesfully
    195  *                          applied or not (optional, can be NULL).
    196  *
    197  * @remarks Maybe called with interrupts disabled in ring-0!
    198  *
    199  * @note    Don't you dare change the delta calculation.  If you really do, make
    200  *          sure you update all places where it's used (IPRT, SUPLibAll.cpp,
    201  *          SUPDrv.c, supdrvGipMpEvent(), and more).
    202  */
    203 DECLINLINE(int) supdrvTscDeltaApply(PSUPGLOBALINFOPAGE pGip, uint64_t *puTsc, uint16_t idApic, bool *pfDeltaApplied)
    204 {
    205     int rc;
    206 
    207     /*
    208      * Validate input.
    209      */
    210     AssertPtr(puTsc);
    211     AssertPtr(pGip);
    212     Assert(pGip->enmUseTscDelta > SUPGIPUSETSCDELTA_ZERO_CLAIMED);
    213 
    214     /*
    215      * Carefully convert the idApic into a GIPCPU entry.
    216      */
    217     if (RT_LIKELY(idApic < RT_ELEMENTS(pGip->aiCpuFromApicId)))
    218     {
    219         uint16_t iCpu = pGip->aiCpuFromApicId[idApic];
    220         if (RT_LIKELY(iCpu < pGip->cCpus))
    221         {
    222             PSUPGIPCPU pGipCpu = &pGip->aCPUs[iCpu];
    223 
    224             /*
    225              * Apply the delta if valid.
    226              */
    227             if (RT_LIKELY(pGipCpu->i64TSCDelta != INT64_MAX))
    228             {
    229                 *puTsc -= pGipCpu->i64TSCDelta;
    230                 if (pfDeltaApplied)
    231                     *pfDeltaApplied = true;
    232                 return VINF_SUCCESS;
    233             }
    234 
    235             rc = VINF_SUCCESS;
    236         }
    237         else
    238         {
    239             AssertMsgFailed(("iCpu=%u cCpus=%u\n", iCpu, pGip->cCpus));
    240             rc = VERR_INVALID_CPU_INDEX;
    241         }
    242     }
    243     else
    244     {
    245         AssertMsgFailed(("idApic=%u\n", idApic));
    246         rc = VERR_INVALID_CPU_ID;
    247     }
    248     if (pfDeltaApplied)
    249         *pfDeltaApplied = false;
    250     return rc;
    251 }
    252187
    253188
     
    771706
    772707/**
    773  * Used by supdrvInitRefineInvariantTscFreqTimer() and
    774  * supdrvGipInitMeasureTscFreq() to update the TSC frequency related GIP
    775  * variables.
     708 * Used by supdrvInitRefineInvariantTscFreqTimer and supdrvGipInitMeasureTscFreq
     709 * to update the TSC frequency related GIP variables.
    776710 *
    777711 * @param   pGip                The GIP.
     
    837771     *         an interrupt handler with higher priority than the clock
    838772     *         interrupt, or spinning for ages in timer handlers is frowned
    839      *         upon, this code must be disabled!
     773     *         upon, this loop must be disabled!
    840774     *
    841775     * Darwin, FreeBSD, Linux, Solaris, Windows 8.1+:
     
    19021836    if (pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC)
    19031837    {
    1904         rc = supdrvGipInitMeasureTscFreq(pDevExt, pGip, true /* fRough */); /* cannot fail */
     1838        rc = supdrvGipInitMeasureTscFreq(pDevExt, pGip, true /*fRough*/); /* cannot fail */
    19051839        supdrvGipInitStartTimerForRefiningInvariantTscFreq(pDevExt, pGip);
    19061840    }
    19071841    else
    1908         rc = supdrvGipInitMeasureTscFreq(pDevExt, pGip, false /* fRough */);
     1842        rc = supdrvGipInitMeasureTscFreq(pDevExt, pGip, false /*fRough*/);
    19091843    if (RT_SUCCESS(rc))
    19101844    {
     
    24392373    {
    24402374        /*
    2441          * The calculations in supdrvGipUpdate() is very timing sensitive and doesn't handle
    2442          * missed timer ticks. So for now it is better to use a delta of 0 and have the TSC rate
    2443          * affected a bit until we get proper TSC deltas than implementing options like
    2444          * rescheduling the tick to be delivered on the right CPU or missing the tick entirely.
     2375         * The calculations in supdrvGipUpdate() is somewhat timing sensitive,
     2376         * missing timer ticks is not an option for GIP because the GIP users
     2377         * will end up incrementing the time in 1ns per time getter call until
     2378         * there is a complete timer update.   So, if the delta has yet to be
     2379         * calculated, we just pretend it is zero for now (the GIP users
     2380         * probably won't have it for a wee while either and will do the same).
    24452381         *
    2446          * The likely hood of this happening is really low. On Windows, Linux, and Solaris
    2447          * timers fire on the CPU they were registered/started on.  Darwin timers doesn't
    2448          * necessarily (they are high priority threads waiting).
     2382         * We could maybe on some platforms try cross calling a CPU with a
     2383         * working delta here, but it's not worth the hassle since the
     2384         * likelyhood of this happening is really low.  On Windows, Linux, and
     2385         * Solaris timers fire on the CPU they were registered/started on.
     2386         * Darwin timers doesn't necessarily (they are high priority threads).
    24492387         */
     2388        uint32_t iCpuSet = RTMpCpuIdToSetIndex(RTMpCpuId());
     2389        uint16_t iGipCpu = RT_LIKELY(iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx))
     2390                         ? pGip->aiCpuFromCpuSetIdx[iCpuSet] : UINT16_MAX;
    24502391        Assert(!ASMIntAreEnabled());
    2451         supdrvTscDeltaApply(pGip, &u64TSC, ASMGetApicId(), NULL /* pfDeltaApplied */);
     2392        if (RT_LIKELY(iGipCpu < pGip->cCpus))
     2393        {
     2394            int64_t iTscDelta = pGip->aCPUs[iGipCpu].i64TSCDelta;
     2395            if (iTscDelta != INT64_MAX)
     2396                u64TSC -= iTscDelta;
     2397        }
    24522398    }
    24532399
     
    31673113 * The idea here is that we have the two CPUs execute the exact same code
    31683114 * collecting a largish set of TSC samples.  The code has one data dependency on
    3169  * the other CPU with the intention to synchronize the execution as well
    3170  * as help cross references the two sets of TSC samples (the sequence numbers).
     3115 * the other CPU which intention it is to synchronize the execution as well as
     3116 * help cross references the two sets of TSC samples (the sequence numbers).
    31713117 *
    31723118 * The @a fLag parameter is used to modify the execution a tiny bit on one or
     
    38213767         */
    38223768        PSUPDRVGIPTSCDELTARGS pArgs = (PSUPDRVGIPTSCDELTARGS)RTMemAllocZ(sizeof(*pArgs));
    3823         if (RT_LIKELY(pArgs))
     3769        if (pArgs)
    38243770        {
    38253771            pArgs->pWorker      = pGipCpuWorker;
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