VirtualBox

Ignore:
Timestamp:
Oct 14, 2014 2:52:50 PM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
96552
Message:

HostDrivers/Support: Kernel thread to service TSC-delta measurement requests. Currently disabled.

Location:
trunk/src/VBox/HostDrivers/Support
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPDrv.c

    r52911 r53054  
    55785578
    55795579
     5580#ifdef SUPDRV_USE_TSC_DELTA_THREAD
     5581/**
     5582 * Switches the TSC-delta measurement thread into the butchered state.
     5583 *
     5584 * @returns VBox status code.
     5585 * @param pDevExt           Pointer to the device instance data.
     5586 * @param fSpinlockHeld     Whether the TSC-delta spinlock is held or not.
     5587 * @param pszFailed         An error message to log.
     5588 * @param rcFailed          The error code to exit the thread with.
     5589 */
     5590static int supdrvTscDeltaThreadButchered(PSUPDRVDEVEXT pDevExt, bool fSpinlockHeld, const char *pszFailed, int rcFailed)
     5591{
     5592    if (!fSpinlockHeld)
     5593        RTSpinlockAcquire(pDevExt->hTscDeltaSpinlock);
     5594
     5595    pDevExt->enmTscDeltaState = kSupDrvTscDeltaState_Butchered;
     5596    RTSpinlockRelease(pDevExt->hTscDeltaSpinlock);
     5597    OSDBGPRINT(("supdrvTscDeltaThreadButchered: %s. rc=%Rrc\n", rcFailed));
     5598    return rcFailed;
     5599}
     5600
     5601
     5602/**
     5603 * The TSC-delta measurement thread.
     5604 *
     5605 * @returns VBox status code.
     5606 * @param hThread   The thread handle.
     5607 * @param pvUser    Opaque pointer to the device instance data.
     5608 */
     5609static DECLCALLBACK(int) supdrvTscDeltaThread(RTTHREAD hThread, void *pvUser)
     5610{
     5611    PSUPDRVDEVEXT     pDevExt = (PSUPDRVDEVEXT)pvUser;
     5612    static uint32_t   cTimesMeasured = 0;
     5613    uint32_t          cConsecutiveTimeouts = 0;
     5614    int               rc = VERR_INTERNAL_ERROR_2;
     5615    for (;;)
     5616    {
     5617        /*
     5618         * Switch on the current state.
     5619         */
     5620        SUPDRVTSCDELTASTATE enmState;
     5621        RTSpinlockAcquire(pDevExt->hTscDeltaSpinlock);
     5622        enmState = pDevExt->enmTscDeltaState;
     5623        switch (enmState)
     5624        {
     5625            case kSupDrvTscDeltaState_Creating:
     5626            {
     5627                pDevExt->enmTscDeltaState = kSupDrvTscDeltaState_Listening;
     5628                rc = RTSemEventSignal(pDevExt->hTscDeltaEvent);
     5629                if (RT_FAILURE(rc))
     5630                    return supdrvTscDeltaThreadButchered(pDevExt, true /* fSpinlockHeld */, "RTSemEventSignal", rc);
     5631                /* fall thru */
     5632            }
     5633
     5634            case kSupDrvTscDeltaState_Listening:
     5635            {
     5636                RTSpinlockRelease(pDevExt->hTscDeltaSpinlock);
     5637
     5638                /* Simple adaptive timeout. */
     5639                if (cConsecutiveTimeouts++ == 10)
     5640                {
     5641                    if (pDevExt->cMsTscDeltaTimeout == 1)           /* 10 ms */
     5642                        pDevExt->cMsTscDeltaTimeout = 10;
     5643                    else if (pDevExt->cMsTscDeltaTimeout == 10)     /* +100 ms */
     5644                        pDevExt->cMsTscDeltaTimeout = 100;
     5645                    else if (pDevExt->cMsTscDeltaTimeout == 100)    /* +1000 ms */
     5646                        pDevExt->cMsTscDeltaTimeout = 500;
     5647                    cConsecutiveTimeouts = 0;
     5648                }
     5649                rc = RTThreadUserWait(pDevExt->hTscDeltaThread, pDevExt->cMsTscDeltaTimeout);
     5650                if (   RT_FAILURE(rc)
     5651                    && rc != VERR_TIMEOUT)
     5652                    return supdrvTscDeltaThreadButchered(pDevExt, false /* fSpinlockHeld */, "RTThreadUserWait", rc);
     5653                break;
     5654            }
     5655
     5656            case kSupDrvTscDeltaState_WaitAndMeasure:
     5657            {
     5658                pDevExt->enmTscDeltaState = kSupDrvTscDeltaState_Measuring;
     5659                rc = RTSemEventSignal(pDevExt->hTscDeltaEvent);
     5660                if (RT_FAILURE(rc))
     5661                    return supdrvTscDeltaThreadButchered(pDevExt, true /* fSpinlockHeld */, "RTSemEventSignal", rc);
     5662                RTSpinlockRelease(pDevExt->hTscDeltaSpinlock);
     5663                pDevExt->cMsTscDeltaTimeout = 1;
     5664                RTThreadSleep(10);
     5665                /* fall thru */
     5666            }
     5667
     5668            case kSupDrvTscDeltaState_Measuring:
     5669            {
     5670                cConsecutiveTimeouts = 0;
     5671                if (!cTimesMeasured++)
     5672                    rc = supdrvMeasureTscDeltas(pDevExt, NULL /* pidxMaster */);
     5673                else
     5674                {
     5675                    PSUPGLOBALINFOPAGE pGip = pDevExt->pGip;
     5676                    unsigned iCpu;
     5677
     5678                    if (cTimesMeasured == UINT32_MAX)
     5679                        cTimesMeasured = 1;
     5680
     5681                    /* Measure TSC-deltas only for the CPUs that are in the set. */
     5682                    rc = VINF_SUCCESS;
     5683                    for (iCpu = 0; iCpu < pGip->cCpus; iCpu++)
     5684                    {
     5685                        PSUPGIPCPU pGipCpuWorker = &pGip->aCPUs[iCpu];
     5686                        if (   pGipCpuWorker->i64TSCDelta == INT64_MAX
     5687                            && RTCpuSetIsMember(&pDevExt->TscDeltaCpuSet, pGipCpuWorker->idCpu))
     5688                        {
     5689                            rc |= supdrvMeasureTscDeltaOne(pDevExt, iCpu);
     5690                            RTCpuSetDel(&pDevExt->TscDeltaCpuSet, pGipCpuWorker->idCpu);
     5691                        }
     5692                    }
     5693                }
     5694                RTSpinlockAcquire(pDevExt->hTscDeltaSpinlock);
     5695                if (pDevExt->enmTscDeltaState == kSupDrvTscDeltaState_Measuring)
     5696                    pDevExt->enmTscDeltaState = kSupDrvTscDeltaState_Listening;
     5697                RTSpinlockRelease(pDevExt->hTscDeltaSpinlock);
     5698                pDevExt->rcTscDelta = rc;
     5699                break;
     5700            }
     5701
     5702            case kSupDrvTscDeltaState_Terminating:
     5703                RTSpinlockRelease(pDevExt->hTscDeltaSpinlock);
     5704                return VINF_SUCCESS;
     5705
     5706            case kSupDrvTscDeltaState_Butchered:
     5707            default:
     5708                return supdrvTscDeltaThreadButchered(pDevExt, true /* fSpinlockHeld */, "Invalid state", VERR_INVALID_STATE);
     5709        }
     5710    }
     5711
     5712    return rc;
     5713}
     5714
     5715
     5716/**
     5717 * Waits for the TSC-delta measurement thread to respond to a state change.
     5718 *
     5719 * @returns VINF_SUCCESS on success, VERR_TIMEOUT if it doesn't respond in time,
     5720 *        other error code on internal error.
     5721 *
     5722 * @param   pThis           Pointer to the grant service instance data.
     5723 * @param   enmCurState     The current state.
     5724 * @param   enmNewState     The new state we're waiting for it to enter.
     5725 */
     5726static int supdrvTscDeltaThreadWait(PSUPDRVDEVEXT pDevExt, SUPDRVTSCDELTASTATE enmCurState, SUPDRVTSCDELTASTATE enmNewState)
     5727{
     5728    /*
     5729     * Wait a short while for the expected state transition.
     5730     */
     5731    int rc;
     5732    RTSemEventWait(pDevExt->hTscDeltaEvent, RT_MS_1SEC);
     5733    RTSpinlockAcquire(pDevExt->hTscDeltaSpinlock);
     5734    if (pDevExt->enmTscDeltaState == enmNewState)
     5735    {
     5736        RTSpinlockRelease(pDevExt->hTscDeltaSpinlock);
     5737        rc = VINF_SUCCESS;
     5738    }
     5739    else if (pDevExt->enmTscDeltaState == enmCurState)
     5740    {
     5741        /*
     5742         * Wait longer if the state has not yet transitioned to the one we want.
     5743         */
     5744        RTSpinlockRelease(pDevExt->hTscDeltaSpinlock);
     5745        rc = RTSemEventWait(pDevExt->hTscDeltaEvent, 50 * RT_MS_1SEC);
     5746        if (   RT_SUCCESS(rc)
     5747            || rc == VERR_TIMEOUT)
     5748        {
     5749            /*
     5750             * Check the state whether we've succeeded.
     5751             */
     5752            SUPDRVTSCDELTASTATE enmState;
     5753            RTSpinlockAcquire(pDevExt->hTscDeltaSpinlock);
     5754            enmState = pDevExt->enmTscDeltaState;
     5755            RTSpinlockRelease(pDevExt->hTscDeltaSpinlock);
     5756            if (enmState == enmNewState)
     5757                rc = VINF_SUCCESS;
     5758            else if (enmState == enmCurState)
     5759            {
     5760                rc = VERR_TIMEOUT;
     5761                OSDBGPRINT(("supdrvTscDeltaThreadWait: timed out state transition. enmState=%d enmNewState=%d\n", enmState,
     5762                            enmNewState));
     5763            }
     5764            else
     5765            {
     5766                rc = VERR_INTERNAL_ERROR;
     5767                OSDBGPRINT(("supdrvTscDeltaThreadWait: invalid state transition from %d to %d, expected %d\n", enmCurState,
     5768                            enmState, enmNewState));
     5769            }
     5770        }
     5771        else
     5772            OSDBGPRINT(("supdrvTscDeltaThreadWait: RTSemEventWait failed. rc=%Rrc\n", rc));
     5773    }
     5774    else
     5775    {
     5776        RTSpinlockRelease(pDevExt->hTscDeltaSpinlock);
     5777        OSDBGPRINT(("supdrvTscDeltaThreadWait: invalid state transition from %d to %d\n", enmCurState, enmNewState));
     5778        rc = VERR_INTERNAL_ERROR;
     5779    }
     5780
     5781    return rc;
     5782}
     5783
     5784
     5785/**
     5786 * Terminates the TSC-delta measurement thread.
     5787 *
     5788 * @param   pDevExt   Pointer to the device instance data.
     5789 */
     5790static void supdrvTscDeltaThreadTerminate(PSUPDRVDEVEXT pDevExt)
     5791{
     5792    int rc;
     5793    RTSpinlockAcquire(pDevExt->hTscDeltaSpinlock);
     5794    pDevExt->enmTscDeltaState = kSupDrvTscDeltaState_Terminating;
     5795    RTSpinlockRelease(pDevExt->hTscDeltaSpinlock);
     5796    RTThreadUserSignal(pDevExt->hTscDeltaThread);
     5797    rc = RTThreadWait(pDevExt->hTscDeltaThread, 50 * RT_MS_1SEC, NULL /* prc */);
     5798    if (RT_FAILURE(rc))
     5799    {
     5800        /* Signal a few more times before giving up. */
     5801        int cTries = 5;
     5802        while (--cTries > 0)
     5803        {
     5804            RTThreadUserSignal(pDevExt->hTscDeltaThread);
     5805            rc = RTThreadWait(pDevExt->hTscDeltaThread, 2 * RT_MS_1SEC, NULL /* prc */);
     5806            if (rc != VERR_TIMEOUT)
     5807                break;
     5808        }
     5809    }
     5810}
     5811
     5812
     5813/**
     5814 * Initializes and spawns the TSC-delta measurement thread.
     5815 *
     5816 * A thread is required for servicing re-measurement requests from events like
     5817 * CPUs coming online, suspend/resume etc. as it cannot be done synchronously
     5818 * under all contexts on all OSs.
     5819 *
     5820 * @returns VBox status code.
     5821 * @param   pDevExt           Pointer to the device instance data.
     5822 *
     5823 * @remarks Must only be called -after- initializing GIP and setting up MP
     5824 *          notifications!
     5825 */
     5826static int supdrvTscDeltaInit(PSUPDRVDEVEXT pDevExt)
     5827{
     5828    int rc = RTSpinlockCreate(&pDevExt->hTscDeltaSpinlock, RTSPINLOCK_FLAGS_INTERRUPT_UNSAFE, "VBoxTscSpnLck");
     5829    if (RT_SUCCESS(rc))
     5830    {
     5831        rc = RTSemEventCreate(&pDevExt->hTscDeltaEvent);
     5832        if (RT_SUCCESS(rc))
     5833        {
     5834            pDevExt->enmTscDeltaState   = kSupDrvTscDeltaState_Creating;
     5835            pDevExt->cMsTscDeltaTimeout = 1;
     5836            RTCpuSetEmpty(&pDevExt->TscDeltaCpuSet);
     5837            rc = RTThreadCreate(&pDevExt->hTscDeltaThread, supdrvTscDeltaThread, pDevExt, 0 /* cbStack */,
     5838                                RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "VBoxTscThread");
     5839            if (RT_SUCCESS(rc))
     5840            {
     5841                rc = supdrvTscDeltaThreadWait(pDevExt, kSupDrvTscDeltaState_Creating, kSupDrvTscDeltaState_Listening);
     5842                if (RT_SUCCESS(rc))
     5843                {
     5844                    pDevExt->rcTscDelta = VERR_NOT_AVAILABLE;
     5845                    return rc;
     5846                }
     5847
     5848                OSDBGPRINT(("supdrvTscDeltaInit: supdrvTscDeltaThreadWait failed. rc=%Rrc\n", rc));
     5849                supdrvTscDeltaThreadTerminate(pDevExt);
     5850            }
     5851            else
     5852                OSDBGPRINT(("supdrvTscDeltaInit: RTThreadCreate failed. rc=%Rrc\n", rc));
     5853            RTSemEventDestroy(pDevExt->hTscDeltaEvent);
     5854            pDevExt->hTscDeltaEvent = NIL_RTSEMEVENT;
     5855        }
     5856        else
     5857            OSDBGPRINT(("supdrvTscDeltaInit: RTSemEventCreate failed. rc=%Rrc\n", rc));
     5858        RTSpinlockDestroy(pDevExt->hTscDeltaSpinlock);
     5859        pDevExt->hTscDeltaSpinlock = NIL_RTSPINLOCK;
     5860    }
     5861    else
     5862        OSDBGPRINT(("supdrvTscDeltaInit: RTSpinlockCreate failed. rc=%Rrc\n", rc));
     5863
     5864    return rc;
     5865}
     5866
     5867
     5868/**
     5869 * Terminates the TSC-delta measurement thread and cleanup.
     5870 *
     5871 * @param   pDevExt         Pointer to the device instance data.
     5872 */
     5873static void supdrvTscDeltaTerm(PSUPDRVDEVEXT pDevExt)
     5874{
     5875    if (   pDevExt->hTscDeltaSpinlock != NIL_RTSPINLOCK
     5876        && pDevExt->hTscDeltaEvent != NIL_RTSEMEVENT)
     5877    {
     5878        supdrvTscDeltaThreadTerminate(pDevExt);
     5879    }
     5880
     5881    if (pDevExt->hTscDeltaSpinlock != NIL_RTSPINLOCK)
     5882    {
     5883        RTSpinlockDestroy(pDevExt->hTscDeltaSpinlock);
     5884        pDevExt->hTscDeltaSpinlock = NIL_RTSPINLOCK;
     5885    }
     5886
     5887    if (pDevExt->hTscDeltaEvent != NIL_RTSEMEVENT)
     5888    {
     5889        RTSemEventDestroy(pDevExt->hTscDeltaEvent);
     5890        pDevExt->hTscDeltaEvent = NIL_RTSEMEVENT;
     5891    }
     5892
     5893    pDevExt->rcTscDelta = VERR_NOT_AVAILABLE;
     5894}
     5895#endif /* SUPDRV_USE_TSC_DELTA_THREAD */
     5896
    55805897
    55815898/**
     
    55945911    int                 rc;
    55955912
    5596 
    55975913    LogFlow(("supdrvGipCreate:\n"));
    55985914
    5599     /* assert order */
     5915    /* Assert order. */
    56005916    Assert(pDevExt->u32SystemTimerGranularityGrant == 0);
    56015917    Assert(pDevExt->GipMemObj == NIL_RTR0MEMOBJ);
     
    56345950    supdrvGipInit(pDevExt, pGip, HCPhysGip, RTTimeSystemNanoTS(), 1000000000 / u32Interval /*=Hz*/, cCpus);
    56355951
    5636     rc = RTMpNotificationRegister(supdrvGipMpEvent, pDevExt);
     5952#ifdef SUPDRV_USE_TSC_DELTA_THREAD
     5953    /* Initialize TSC-delta measurement thread before executing any Mp event callbacks. */
     5954    rc = supdrvTscDeltaInit(pDevExt);
     5955#endif
    56375956    if (RT_SUCCESS(rc))
    56385957    {
    5639         rc = RTMpOnAll(supdrvGipInitOnCpu, pDevExt, pGip);
     5958        rc = RTMpNotificationRegister(supdrvGipMpEvent, pDevExt);
    56405959        if (RT_SUCCESS(rc))
    56415960        {
    5642             /*
    5643              * Measure the TSC deltas now that we have MP notifications.
    5644              */
    5645             unsigned cTries = 5;
    5646             do
    5647             {
    5648                 rc = supdrvMeasureTscDeltas(pDevExt, NULL /* pidxMaster */);
    5649                 if (rc == VERR_TRY_AGAIN)
     5961            rc = RTMpOnAll(supdrvGipInitOnCpu, pDevExt, pGip);
     5962            if (RT_SUCCESS(rc))
     5963            {
     5964#ifndef SUPDRV_USE_TSC_DELTA_THREAD
     5965                /*
     5966                 * Measure the TSC deltas now that we have MP notifications.
     5967                 */
     5968                int      cTries = 5;
     5969                uint16_t iCpu;
     5970                do
    56505971                {
    5651                     --cTries;
    5652                     continue;
    5653                 }
    5654                 else
    5655                     break;
    5656             } while (cTries > 0);
    5657             if (RT_SUCCESS(rc))
    5658             {
    5659 #ifdef DEBUG_ramshankar
    5660                 for (unsigned iCpu = 0; iCpu < pGip->cCpus; iCpu++)
    5661                     OSDBGPRINT(("supdrvGipCreate: cpu[%u] delta %lld\n", iCpu, pGip->aCPUs[iCpu].i64TSCDelta));
     5972                    rc = supdrvMeasureTscDeltas(pDevExt, NULL /* pidxMaster */);
     5973                    if (rc != VERR_TRY_AGAIN)
     5974                        break;
     5975                } while (--cTries > 0);
     5976                for (iCpu = 0; iCpu < pGip->cCpus; iCpu++)
     5977                    Log(("supdrvTscDeltaInit: cpu[%u] delta %lld\n", iCpu, pGip->aCPUs[iCpu].i64TSCDelta));
    56625978#endif
    56635979
     
    56936009            }
    56946010            else
    5695                 OSDBGPRINT(("supdrvGipCreate: supdrvMeasureTscDeltas() failed with rc=%Rrc after %u tries!\n", rc, cTries));
     6011                OSDBGPRINT(("supdrvGipCreate: RTMpOnAll failed. rc=%Rrc\n", rc));
    56966012        }
    56976013        else
    5698             OSDBGPRINT(("supdrvGipCreate: RTMpOnAll failed with rc=%Rrc\n", rc));
    5699 
    5700         RTMpNotificationDeregister(supdrvGipMpEvent, pDevExt);
     6014            OSDBGPRINT(("supdrvGipCreate: failed to register MP event notfication. rc=%Rrc\n", rc));
    57016015    }
    57026016    else
    5703         OSDBGPRINT(("supdrvGipCreate: failed to register MP event notfication. rc=%Rrc\n", rc));
     6017        OSDBGPRINT(("supdrvGipCreate: supdrvTscDeltaInit failed. rc=%Rrc\n", rc));
    57046018
    57056019    supdrvGipDestroy(pDevExt);
     
    57206034                pDevExt->GipMemObj != NIL_RTR0MEMOBJ ? RTR0MemObjAddress(pDevExt->GipMemObj) : NULL,
    57216035                pDevExt->pGipTimer, pDevExt->GipMemObj));
     6036#endif
     6037
     6038    /*
     6039     * Stop receiving MP notifications before tearing anything else down.
     6040     */
     6041    RTMpNotificationDeregister(supdrvGipMpEvent, pDevExt);
     6042
     6043#ifdef SUPDRV_USE_TSC_DELTA_THREAD
     6044    /*
     6045     * Terminate the TSC-delta measurement thread and resources.
     6046     */
     6047    supdrvTscDeltaTerm(pDevExt);
    57226048#endif
    57236049
     
    58926218    /* Update the Mp online/offline counter. */
    58936219    ASMAtomicIncU32(&g_cMpOnOffEvents);
     6220
     6221#ifdef SUPDRV_USE_TSC_DELTA_THREAD
     6222    /*
     6223     * Add this CPU to the set of CPUs that require their TSC delta to be measured.
     6224     *
     6225     * We cannot poke the TSC-delta measurement thread from this context (on all OSs), so we only
     6226     * update the state and it'll get serviced when the thread's listening interval times out.
     6227     */
     6228    RTCpuSetAdd(&pDevExt->TscDeltaCpuSet, idCpu);
     6229    RTSpinlockAcquire(pDevExt->hTscDeltaSpinlock);
     6230    if (   pDevExt->enmTscDeltaState == kSupDrvTscDeltaState_Listening
     6231        || pDevExt->enmTscDeltaState == kSupDrvTscDeltaState_Measuring)
     6232    {
     6233        pDevExt->enmTscDeltaState = kSupDrvTscDeltaState_WaitAndMeasure;
     6234    }
     6235    RTSpinlockRelease(pDevExt->hTscDeltaSpinlock);
     6236#endif
    58946237
    58956238    /* commit it */
  • trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h

    r52575 r53054  
    231231#endif
    232232
     233#if 0
     234/**  Use a dedicated kernel thread to service TSC-delta measurement requests. */
     235#define SUPDRV_USE_TSC_DELTA_THREAD
     236#endif
    233237
    234238/*******************************************************************************
     
    238242typedef struct SUPDRVDEVEXT *PSUPDRVDEVEXT;
    239243
     244#ifdef SUPDRV_USE_TSC_DELTA_THREAD
     245/**
     246 * TSC-delta measurement thread state machine.
     247 */
     248typedef enum SUPDRVTSCDELTASTATE
     249{
     250    /** Uninitialized/invalid value. */
     251    kSupDrvTscDeltaState_Invalid = 0,
     252    /** The thread is being created. */
     253    kSupDrvTscDeltaState_Creating,
     254    /** The thread is listening for events. */
     255    kSupDrvTscDeltaState_Listening,
     256    /** The thread is sleeping before starting a measurement. */
     257    kSupDrvTscDeltaState_WaitAndMeasure,
     258    /** The thread is currently servicing a measurement request. */
     259    kSupDrvTscDeltaState_Measuring,
     260    /** The thread is terminating. */
     261    kSupDrvTscDeltaState_Terminating,
     262    /** The thread is butchered due to an unexpected error. */
     263    kSupDrvTscDeltaState_Butchered,
     264    /** The thread is destroyed. */
     265    kSupDrvTscDeltaState_Destroyed,
     266    /** The usual 32-bit blowup hack. */
     267    kSupDrvTscDeltaState_32BitHack = 0x7fffffff
     268} SUPDRVTSCDELTASTATE;
     269#endif
    240270
    241271/**
     
    648678    /** @} */
    649679
     680#ifdef SUPDRV_USE_TSC_DELTA_THREAD
     681    /** @name TSC-delta measurement.
     682     *  @{ */
     683    /** Spinlock protecting enmTscDeltaState. */
     684    RTSPINLOCK                      hTscDeltaSpinlock;
     685    /** TSC-delta measurement thread. */
     686    RTTHREAD                        hTscDeltaThread;
     687    /** The event signalled during state changes to the TSC-delta thread. */
     688    RTSEMEVENT                      hTscDeltaEvent;
     689    /** The state of the TSC-delta measurement thread. */
     690    SUPDRVTSCDELTASTATE             enmTscDeltaState;
     691    /** Thread timeout time before rechecking state in ms. */
     692    RTMSINTERVAL                    cMsTscDeltaTimeout;
     693    /** The set of CPUs we need to take measurements for. */
     694    RTCPUSET                        TscDeltaCpuSet;
     695    /** Whether the TSC-delta measurement was successful. */
     696    int                             rcTscDelta;
     697    /** @} */
     698#endif
     699
    650700    /*
    651701     * Note! The non-agnostic bits must be at the very end of the structure!
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