VirtualBox

Changeset 54489 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Feb 25, 2015 1:02:11 PM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
98597
Message:

SUPDrvGip.cpp: Simplify the data structures for the TSC measurements, drop the per-method init/delete stuff.

File:
1 edited

Legend:

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

    r54480 r54489  
    25732573 * Argument package/state passed by supdrvMeasureTscDeltaOne() to the RTMpOn
    25742574 * callback worker.
     2575 * @todo add
    25752576 */
    25762577typedef struct SUPDRVGIPTSCDELTARGS
     
    26002601        PSUPDRVTSCDELTAMETHOD2  pMasterData;
    26012602        PSUPDRVTSCDELTAMETHOD2  pWorkerData;
    2602         uint32_t                cHits;
    2603         bool                    fLagMaster;
    2604         bool                    fLagWorker;
    26052603    } M2;
    26062604#endif
     
    26172615    /** Pointer to the master's synchronization struct (on stack). */
    26182616    PSUPTSCDELTASYNC2 volatile  pSyncMaster;
    2619     /** Verification test TSC values for the master. */
    2620     uint64_t volatile           auVerifyMasterTscs[32];
     2617    /** Master data union. */
     2618    union
     2619    {
     2620        /** Data (master) for delta verification. */
     2621        struct
     2622        {
     2623            /** Verification test TSC values for the master. */
     2624            uint64_t volatile       auTscs[32];
     2625        } Verify;
     2626        /** Data (master) for measurement method \#2. */
     2627        struct
     2628        {
     2629            /** Data and sequence number. */
     2630            SUPDRVTSCDELTAMETHOD2   Data;
     2631            /** The lag setting for the next run. */
     2632            bool                    fLag;
     2633            /** Number of hits. */
     2634            uint32_t                cHits;
     2635        } M2;
     2636    } uMaster;
    26212637    /** The verifier verdict, VINF_SUCCESS if ok, VERR_OUT_OF_RANGE if not,
    26222638     * VERR_TRY_AGAIN on timeout. */
     
    26382654    /** The time the worker spent in the MP worker.  */
    26392655    uint64_t                    cElapsedWorkerTscTicks;
    2640     /** Verification test TSC values for the worker. */
    2641     uint64_t volatile           auVerifyWorkerTscs[32];
     2656    /** Worker data union. */
     2657    union
     2658    {
     2659        /** Data (worker) for delta verification. */
     2660        struct
     2661        {
     2662            /** Verification test TSC values for the worker. */
     2663            uint64_t volatile       auTscs[32];
     2664        } Verify;
     2665        /** Data (worker) for measurement method \#2. */
     2666        struct
     2667        {
     2668            /** Data and sequence number. */
     2669            SUPDRVTSCDELTAMETHOD2   Data;
     2670            /** The lag setting for the next run (set by master). */
     2671            bool                    fLag;
     2672        } M2;
     2673    } uWorker;
    26422674
    26432675    /** Padding to make sure the above is in its own cache line. */
     
    29532985/** @} */
    29542986
     2987
    29552988#ifdef GIP_TSC_DELTA_METHOD_1
    2956 
    29572989/**
    29582990 * TSC delta measurment algorithm \#1 (GIP_TSC_DELTA_METHOD_1).
     
    30943126        ASMAtomicWriteU64(&pGipCpuWorker->u64TSCSample, GIP_TSC_DELTA_RSVD);
    30953127}
    3096 
    3097 
    3098 /**
    3099  * Initializes the argument/state data belonging to algorithm \#1.
    3100  *
    3101  * @returns VBox status code.
    3102  * @param   pArgs               The argument/state data.
    3103  */
    3104 static int supdrvTscDeltaMethod1Init(PSUPDRVGIPTSCDELTARGS pArgs)
    3105 {
    3106     NOREF(pArgs);
    3107     return VINF_SUCCESS;
    3108 }
    3109 
    3110 
    3111 /**
    3112  * Undoes what supdrvTscDeltaMethod1Init() did.
    3113  *
    3114  * @param   pArgs               The argument/state data.
    3115  */
    3116 static void supdrvTscDeltaMethod1Delete(PSUPDRVGIPTSCDELTARGS pArgs)
    3117 {
    3118     NOREF(pArgs);
    3119 }
    3120 
    31213128#endif /* GIP_TSC_DELTA_METHOD_1 */
    31223129
     
    31713178    if (cHits > 2)
    31723179        pArgs->pWorker->i64TSCDelta = iBestDelta;
    3173     pArgs->M2.cHits += cHits;
     3180    pArgs->uMaster.M2.cHits += cHits;
    31743181}
    31753182
     
    32453252            {
    32463253                /* Lag during the priming to be nice to everyone.. */
    3247                 pArgs->M2.fLagMaster = true;
    3248                 pArgs->M2.fLagWorker = true;
     3254                pArgs->uMaster.M2.fLag = true;
     3255                pArgs->uWorker.M2.fLag = true;
    32493256            }
    32503257            else
     
    32533260            {
    32543261                /* 25 % of the body without lagging. */
    3255                 pArgs->M2.fLagMaster = false;
    3256                 pArgs->M2.fLagWorker = false;
     3262                pArgs->uMaster.M2.fLag = false;
     3263                pArgs->uWorker.M2.fLag = false;
    32573264            }
    32583265            else if (iLoop < (GIP_TSC_DELTA_M2_LOOPS - GIP_TSC_DELTA_M2_PRIMER_LOOPS) / 4 * 2)
    32593266            {
    32603267                /* 25 % of the body with both lagging. */
    3261                 pArgs->M2.fLagMaster = true;
    3262                 pArgs->M2.fLagWorker = true;
     3268                pArgs->uMaster.M2.fLag = true;
     3269                pArgs->uWorker.M2.fLag = true;
    32633270            }
    32643271            else
    32653272            {
    32663273                /* 50% of the body with alternating lag. */
    3267                 pArgs->M2.fLagMaster = (iLoop & 1) == 0;
    3268                 pArgs->M2.fLagWorker = (iLoop & 1) == 1;
     3274                pArgs->uMaster.M2.fLag = (iLoop & 1) == 0;
     3275                pArgs->uWorker.M2.fLag= (iLoop & 1) == 1;
    32693276            }
    32703277
     
    32733280             */
    32743281            TSCDELTA_MASTER_SYNC_BEFORE(pMySync, pOtherSync, &fEFlags, pArgs);
    3275             supdrvTscDeltaMethod2CollectData(pArgs->M2.pMasterData, &pArgs->M2.pWorkerData->iCurSeqNo, pArgs->M2.fLagMaster);
     3282            supdrvTscDeltaMethod2CollectData(&pArgs->uMaster.M2.Data, &pArgs->uWorker.M2.Data.iCurSeqNo, pArgs->uMaster.M2.fLag);
    32763283            TSCDELTA_MASTER_SYNC_AFTER(pMySync, pOtherSync, fEFlags);
    32773284
     
    32923299             */
    32933300            TSCDELTA_OTHER_SYNC_BEFORE(pMySync, pOtherSync, &fEFlags, pArgs);
    3294             supdrvTscDeltaMethod2CollectData(pArgs->M2.pWorkerData, &pArgs->M2.pMasterData->iCurSeqNo, pArgs->M2.fLagWorker);
     3301            supdrvTscDeltaMethod2CollectData(&pArgs->uWorker.M2.Data, &pArgs->uMaster.M2.Data.iCurSeqNo, pArgs->uWorker.M2.fLag);
    32953302            TSCDELTA_OTHER_SYNC_AFTER(pMySync, pOtherSync, fEFlags);
    32963303        }
    32973304    }
    32983305}
    3299 
    3300 
    3301 /**
    3302  * Initializes the argument/state data belonging to algorithm \#2.
    3303  *
    3304  * @returns VBox status code.
    3305  * @param   pArgs               The argument/state data.
    3306  */
    3307 static int supdrvTscDeltaMethod2Init(PSUPDRVGIPTSCDELTARGS pArgs)
    3308 {
    3309     pArgs->M2.pMasterData = NULL;
    3310     pArgs->M2.pWorkerData = NULL;
    3311 
    3312     uint32_t const fFlags = /*RTMEMALLOCEX_FLAGS_ANY_CTX |*/ RTMEMALLOCEX_FLAGS_ZEROED;
    3313     int rc = RTMemAllocEx(sizeof(*pArgs->M2.pWorkerData), 0, fFlags, (void **)&pArgs->M2.pWorkerData);
    3314     if (RT_SUCCESS(rc))
    3315         rc = RTMemAllocEx(sizeof(*pArgs->M2.pMasterData), 0, fFlags, (void **)&pArgs->M2.pMasterData);
    3316     return rc;
    3317 }
    3318 
    3319 
    3320 /**
    3321  * Undoes what supdrvTscDeltaMethod2Init() did.
    3322  *
    3323  * @param   pArgs               The argument/state data.
    3324  */
    3325 static void supdrvTscDeltaMethod2Delete(PSUPDRVGIPTSCDELTARGS pArgs)
    3326 {
    3327     RTMemFreeEx(pArgs->M2.pMasterData, sizeof(*pArgs->M2.pMasterData));
    3328     RTMemFreeEx(pArgs->M2.pWorkerData, sizeof(*pArgs->M2.pWorkerData));
    3329 # if 0
    3330     SUPR0Printf("cHits=%d m=%d w=%d\n", pArgs->M2.cHits, pArgs->pMaster->idApic, pArgs->pWorker->idApic);
    3331 # endif
    3332 }
    3333 
    33343306
    33353307#endif /* GIP_TSC_DELTA_METHOD_2 */
     
    33483320    {
    33493321        RTCCUINTREG fEFlags;
    3350         AssertCompile((RT_ELEMENTS(pArgs->auVerifyMasterTscs) & 1) == 0);
    3351         AssertCompile(RT_ELEMENTS(pArgs->auVerifyWorkerTscs) == RT_ELEMENTS(pArgs->auVerifyMasterTscs));
     3322        AssertCompile((RT_ELEMENTS(pArgs->uMaster.Verify.auTscs) & 1) == 0);
     3323        AssertCompile(RT_ELEMENTS(pArgs->uMaster.Verify.auTscs) == RT_ELEMENTS(pArgs->uWorker.Verify.auTscs));
    33523324
    33533325        if (fIsMaster)
     
    33593331             * Collect TSC, master goes first.
    33603332             */
    3361             for (i = 0; i < RT_ELEMENTS(pArgs->auVerifyMasterTscs); i += 2)
     3333            for (i = 0; i < RT_ELEMENTS(pArgs->uMaster.Verify.auTscs); i += 2)
    33623334            {
    33633335                /* Read, kick & wait #1. */
     
    33653337                ASMAtomicWriteU32(&pOtherSync->uSyncVar, GIP_TSC_DELTA_SYNC2_GO_GO);
    33663338                ASMSerializeInstruction();
    3367                 pArgs->auVerifyMasterTscs[i] = uTsc;
     3339                pArgs->uMaster.Verify.auTscs[i] = uTsc;
    33683340                TSCDELTA_DBG_START_LOOP();
    33693341                while (ASMAtomicReadU32(&pMySync->uSyncVar) == GIP_TSC_DELTA_SYNC2_GO)
     
    33773349                ASMAtomicWriteU32(&pOtherSync->uSyncVar, GIP_TSC_DELTA_SYNC2_GO);
    33783350                ASMSerializeInstruction();
    3379                 pArgs->auVerifyMasterTscs[i + 1] = uTsc;
     3351                pArgs->uMaster.Verify.auTscs[i + 1] = uTsc;
    33803352                TSCDELTA_DBG_START_LOOP();
    33813353                while (ASMAtomicReadU32(&pMySync->uSyncVar) == GIP_TSC_DELTA_SYNC2_GO_GO)
     
    33983370            ASMAtomicWriteS32(&pArgs->rcVerify, VINF_SUCCESS);
    33993371            uTscWorker = 0;
    3400             for (i = 0; i < RT_ELEMENTS(pArgs->auVerifyMasterTscs); i++)
     3372            for (i = 0; i < RT_ELEMENTS(pArgs->uMaster.Verify.auTscs); i++)
    34013373            {
    34023374                /* Master vs previous worker entry. */
    3403                 uint64_t uTscMaster = pArgs->auVerifyMasterTscs[i] - pGipCpuMaster->i64TSCDelta;
     3375                uint64_t uTscMaster = pArgs->uMaster.Verify.auTscs[i] - pGipCpuMaster->i64TSCDelta;
    34043376                int64_t  iDiff;
    34053377                if (i > 0)
     
    34233395
    34243396                /* Worker vs master. */
    3425                 uTscWorker = pArgs->auVerifyWorkerTscs[i] - iWorkerTscDelta;
     3397                uTscWorker = pArgs->uWorker.Verify.auTscs[i] - iWorkerTscDelta;
    34263398                iDiff = uTscWorker - uTscMaster;
    34273399#ifdef TSCDELTA_VERIFY_WITH_STATS
     
    34513423            TSCDELTA_OTHER_SYNC_BEFORE(pMySync, pOtherSync, &fEFlags, pArgs);
    34523424
    3453             for (i = 0; i < RT_ELEMENTS(pArgs->auVerifyWorkerTscs); i += 2)
     3425            for (i = 0; i < RT_ELEMENTS(pArgs->uWorker.Verify.auTscs); i += 2)
    34543426            {
    34553427                uint64_t register uTsc;
     
    34653437                ASMAtomicWriteU32(&pOtherSync->uSyncVar, GIP_TSC_DELTA_SYNC2_GO_GO);
    34663438                ASMSerializeInstruction();
    3467                 pArgs->auVerifyWorkerTscs[i] = uTsc;
     3439                pArgs->uWorker.Verify.auTscs[i] = uTsc;
    34683440
    34693441                /* Wait, Read and Kick #2. */
     
    34773449                ASMAtomicWriteU32(&pOtherSync->uSyncVar, GIP_TSC_DELTA_SYNC2_GO);
    34783450                ASMSerializeInstruction();
    3479                 pArgs->auVerifyWorkerTscs[i + 1] = uTsc;
     3451                pArgs->uWorker.Verify.auTscs[i + 1] = uTsc;
    34803452            }
    34813453
     
    38643836            pArgs->cMaxTscTicks = ASMAtomicReadU64(&pGip->u64CpuHz) / 512; /* 1953 us */
    38653837
    3866 #ifdef GIP_TSC_DELTA_METHOD_1
    3867             rc = supdrvTscDeltaMethod1Init(pArgs);
    3868 #elif defined(GIP_TSC_DELTA_METHOD_2)
    3869             rc = supdrvTscDeltaMethod2Init(pArgs);
    3870 #else
    3871 # error "huh?"
    3872 #endif
     3838            /*
     3839             * Do the RTMpOnPair call.  We reset i64TSCDelta first so we
     3840             * and supdrvMeasureTscDeltaCallback can use it as a success check.
     3841             */
     3842            /** @todo Store the i64TSCDelta result in pArgs first?   Perhaps deals with
     3843             *        that when doing the restart loop reorg.  */
     3844            ASMAtomicWriteS64(&pGipCpuWorker->i64TSCDelta, INT64_MAX);
     3845            rc = RTMpOnPair(pGipCpuMaster->idCpu, pGipCpuWorker->idCpu, RTMPON_F_CONCURRENT_EXEC,
     3846                            supdrvMeasureTscDeltaCallback, pArgs, NULL);
    38733847            if (RT_SUCCESS(rc))
    38743848            {
    3875                 /*
    3876                  * Do the RTMpOnPair call.  We reset i64TSCDelta first so we
    3877                  * and supdrvMeasureTscDeltaCallback can use it as a success check.
    3878                  */
    3879                 /** @todo Store the i64TSCDelta result in pArgs first?   Perhaps deals with
    3880                  *        that when doing the restart loop reorg.  */
    3881                 ASMAtomicWriteS64(&pGipCpuWorker->i64TSCDelta, INT64_MAX);
    3882                 rc = RTMpOnPair(pGipCpuMaster->idCpu, pGipCpuWorker->idCpu, RTMPON_F_CONCURRENT_EXEC,
    3883                                 supdrvMeasureTscDeltaCallback, pArgs, NULL);
    3884                 if (RT_SUCCESS(rc))
    3885                 {
    38863849#if 0
    3887                     SUPR0Printf("mponpair ticks: %9llu %9llu  max: %9llu  iTry: %u%s\n", pArgs->cElapsedMasterTscTicks,
    3888                                 pArgs->cElapsedWorkerTscTicks, pArgs->cMaxTscTicks, pArgs->iTry,
    3889                                 pArgs->fTimedOut ? " timed out" :"");
     3850                SUPR0Printf("mponpair ticks: %9llu %9llu  max: %9llu  iTry: %u%s\n", pArgs->cElapsedMasterTscTicks,
     3851                            pArgs->cElapsedWorkerTscTicks, pArgs->cMaxTscTicks, pArgs->iTry,
     3852                            pArgs->fTimedOut ? " timed out" :"");
    38903853#endif
    38913854#if 0
    3892                     SUPR0Printf("rcVerify=%d iVerifyBadTscDiff=%lld cMinVerifyTscTicks=%lld cMaxVerifyTscTicks=%lld\n",
    3893                                 pArgs->rcVerify, pArgs->iVerifyBadTscDiff, pArgs->cMinVerifyTscTicks, pArgs->cMaxVerifyTscTicks);
     3855                SUPR0Printf("rcVerify=%d iVerifyBadTscDiff=%lld cMinVerifyTscTicks=%lld cMaxVerifyTscTicks=%lld\n",
     3856                            pArgs->rcVerify, pArgs->iVerifyBadTscDiff, pArgs->cMinVerifyTscTicks, pArgs->cMaxVerifyTscTicks);
    38943857#endif
    3895                     if (RT_LIKELY(pGipCpuWorker->i64TSCDelta != INT64_MAX))
     3858                if (RT_LIKELY(pGipCpuWorker->i64TSCDelta != INT64_MAX))
     3859                {
     3860                    /*
     3861                     * Work the TSC delta applicability rating.  It starts
     3862                     * optimistic in supdrvGipInit, we downgrade it here.
     3863                     */
     3864                    SUPGIPUSETSCDELTA enmRating;
     3865                    if (   pGipCpuWorker->i64TSCDelta >  GIP_TSC_DELTA_THRESHOLD_ROUGHLY_ZERO
     3866                        || pGipCpuWorker->i64TSCDelta < -GIP_TSC_DELTA_THRESHOLD_ROUGHLY_ZERO)
     3867                        enmRating = SUPGIPUSETSCDELTA_NOT_ZERO;
     3868                    else if (   pGipCpuWorker->i64TSCDelta >  GIP_TSC_DELTA_THRESHOLD_PRACTICALLY_ZERO
     3869                             || pGipCpuWorker->i64TSCDelta < -GIP_TSC_DELTA_THRESHOLD_PRACTICALLY_ZERO)
     3870                        enmRating = SUPGIPUSETSCDELTA_ROUGHLY_ZERO;
     3871                    else
     3872                        enmRating = SUPGIPUSETSCDELTA_PRACTICALLY_ZERO;
     3873                    if (pGip->enmUseTscDelta < enmRating)
    38963874                    {
    3897                         /*
    3898                          * Work the TSC delta applicability rating.  It starts
    3899                          * optimistic in supdrvGipInit, we downgrade it here.
    3900                          */
    3901                         SUPGIPUSETSCDELTA enmRating;
    3902                         if (   pGipCpuWorker->i64TSCDelta >  GIP_TSC_DELTA_THRESHOLD_ROUGHLY_ZERO
    3903                             || pGipCpuWorker->i64TSCDelta < -GIP_TSC_DELTA_THRESHOLD_ROUGHLY_ZERO)
    3904                             enmRating = SUPGIPUSETSCDELTA_NOT_ZERO;
    3905                         else if (   pGipCpuWorker->i64TSCDelta >  GIP_TSC_DELTA_THRESHOLD_PRACTICALLY_ZERO
    3906                                  || pGipCpuWorker->i64TSCDelta < -GIP_TSC_DELTA_THRESHOLD_PRACTICALLY_ZERO)
    3907                             enmRating = SUPGIPUSETSCDELTA_ROUGHLY_ZERO;
    3908                         else
    3909                             enmRating = SUPGIPUSETSCDELTA_PRACTICALLY_ZERO;
    3910                         if (pGip->enmUseTscDelta < enmRating)
    3911                         {
    3912                             AssertCompile(sizeof(pGip->enmUseTscDelta) == sizeof(uint32_t));
    3913                             ASMAtomicWriteU32((uint32_t volatile *)&pGip->enmUseTscDelta, enmRating);
    3914                         }
     3875                        AssertCompile(sizeof(pGip->enmUseTscDelta) == sizeof(uint32_t));
     3876                        ASMAtomicWriteU32((uint32_t volatile *)&pGip->enmUseTscDelta, enmRating);
    39153877                    }
    3916                     else
    3917                         rc = VERR_SUPDRV_TSC_DELTA_MEASUREMENT_FAILED;
    39183878                }
    3919                 /** @todo return try-again if we get an offline CPU error.   */
     3879                else
     3880                    rc = VERR_SUPDRV_TSC_DELTA_MEASUREMENT_FAILED;
    39203881            }
    3921 
    3922 #ifdef GIP_TSC_DELTA_METHOD_1
    3923             supdrvTscDeltaMethod1Delete(pArgs);
    3924 #elif defined(GIP_TSC_DELTA_METHOD_2)
    3925             supdrvTscDeltaMethod2Delete(pArgs);
    3926 #else
    3927 # error "huh?"
    3928 #endif
     3882            /** @todo return try-again if we get an offline CPU error.   */
     3883
    39293884            RTMemFree(pArgs);
    39303885        }
Note: See TracChangeset for help on using the changeset viewer.

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