VirtualBox

Changeset 87748 in vbox for trunk


Ignore:
Timestamp:
Feb 13, 2021 3:03:20 AM (4 years ago)
Author:
vboxsync
Message:

TM: Speed up TMNotifyEndOfExecution by using TSC instead of RTTimeNanoTS() to measure time spend in guest context. Should give 5-10% speedup. bugref:9941

Location:
trunk/src/VBox/VMM
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/TMAll.cpp

    r82968 r87748  
    159159{
    160160#ifndef VBOX_WITHOUT_NS_ACCOUNTING
    161     pVCpu->tm.s.u64NsTsStartExecuting = RTTimeNanoTS();
     161    pVCpu->tm.s.uTscStartExecuting = SUPReadTsc();
     162    pVCpu->tm.s.fExecuting         = true;
    162163#endif
    163164    if (pVM->tm.s.fTSCTiedToExecution)
     
    183184
    184185#ifndef VBOX_WITHOUT_NS_ACCOUNTING
    185     uint64_t const u64NsTs           = RTTimeNanoTS();
    186     uint64_t const cNsTotalNew       = u64NsTs - pVCpu->tm.s.u64NsTsStartTotal;
    187     uint64_t const cNsExecutingDelta = u64NsTs - pVCpu->tm.s.u64NsTsStartExecuting;
    188     uint64_t const cNsExecutingNew   = pVCpu->tm.s.cNsExecuting + cNsExecutingDelta;
    189     uint64_t const cNsOtherNew       = cNsTotalNew - cNsExecutingNew - pVCpu->tm.s.cNsHalted;
    190 
     186    /*
     187     * Calculate the elapsed tick count and convert it to nanoseconds.
     188     */
     189    /** @todo get TSC from caller (HMR0A.asm) */
     190    uint64_t       cTicks            = SUPReadTsc() - pVCpu->tm.s.uTscStartExecuting;
     191# ifdef IN_RING3
     192    uint64_t const uCpuHz            = SUPGetCpuHzFromGip(g_pSUPGlobalInfoPage);
     193# else
     194    uint64_t const uCpuHz            = SUPGetCpuHzFromGipBySetIndex(g_pSUPGlobalInfoPage, pVCpu->iHostCpuSet);
     195# endif
     196    AssertStmt(cTicks <= uCpuHz << 2, cTicks = uCpuHz << 2); /* max 4 sec */
     197
     198    uint64_t cNsExecutingDelta;
     199    if (uCpuHz < _4G)
     200        cNsExecutingDelta = ASMMultU64ByU32DivByU32(cTicks, RT_NS_1SEC, uCpuHz);
     201    else if (uCpuHz < 16*_1G64)
     202        cNsExecutingDelta = ASMMultU64ByU32DivByU32(cTicks >> 2, RT_NS_1SEC, uCpuHz >> 2);
     203    else
     204    {
     205        Assert(uCpuHz < 64 * _1G64);
     206        cNsExecutingDelta = ASMMultU64ByU32DivByU32(cTicks >> 4, RT_NS_1SEC, uCpuHz >> 4);
     207    }
     208
     209    /*
     210     * Update the data.
     211     */
     212    uint64_t const cNsExecutingNew = pVCpu->tm.s.cNsExecuting + cNsExecutingDelta;
     213    /** @todo try relax ordering here */
     214    uint32_t uGen = ASMAtomicIncU32(&pVCpu->tm.s.uTimesGen); Assert(uGen & 1);
     215    pVCpu->tm.s.fExecuting   = false;
     216    pVCpu->tm.s.cNsExecuting = cNsExecutingNew;
     217    pVCpu->tm.s.cPeriodsExecuting++;
     218    ASMAtomicWriteU32(&pVCpu->tm.s.uTimesGen, (uGen | 1) + 1);
     219
     220    /*
     221     * Update stats.
     222     */
    191223# if defined(VBOX_WITH_STATISTICS) || defined(VBOX_WITH_NS_ACCOUNTING_STATS)
    192224    STAM_REL_PROFILE_ADD_PERIOD(&pVCpu->tm.s.StatNsExecuting, cNsExecutingDelta);
     
    197229    else
    198230        STAM_REL_PROFILE_ADD_PERIOD(&pVCpu->tm.s.StatNsExecLong, cNsExecutingDelta);
    199     STAM_REL_COUNTER_ADD(&pVCpu->tm.s.StatNsTotal, cNsTotalNew - pVCpu->tm.s.cNsTotal);
    200     int64_t  const cNsOtherNewDelta  = cNsOtherNew - pVCpu->tm.s.cNsOther;
    201     if (cNsOtherNewDelta > 0)
    202         STAM_REL_PROFILE_ADD_PERIOD(&pVCpu->tm.s.StatNsOther, cNsOtherNewDelta); /* (the period before execution) */
    203231# endif
    204232
    205     uint32_t uGen = ASMAtomicIncU32(&pVCpu->tm.s.uTimesGen); Assert(uGen & 1);
    206     pVCpu->tm.s.cNsExecuting = cNsExecutingNew;
    207     pVCpu->tm.s.cNsTotal     = cNsTotalNew;
    208     pVCpu->tm.s.cNsOther     = cNsOtherNew;
    209     pVCpu->tm.s.cPeriodsExecuting++;
    210     ASMAtomicWriteU32(&pVCpu->tm.s.uTimesGen, (uGen | 1) + 1);
     233    /* The timer triggers occational updating of the others and total stats: */
     234    if (RT_LIKELY(!pVCpu->tm.s.fUpdateStats))
     235    { /*likely*/ }
     236    else
     237    {
     238        pVCpu->tm.s.fUpdateStats = false;
     239
     240        uint64_t const cNsTotalNew = RTTimeNanoTS() - pVCpu->tm.s.nsStartTotal;
     241        uint64_t const cNsOtherNew = cNsTotalNew - cNsExecutingNew - pVCpu->tm.s.cNsHalted;
     242
     243# if defined(VBOX_WITH_STATISTICS) || defined(VBOX_WITH_NS_ACCOUNTING_STATS)
     244        STAM_REL_COUNTER_ADD(&pVCpu->tm.s.StatNsTotal, cNsTotalNew - pVCpu->tm.s.cNsTotalStat);
     245        int64_t const cNsOtherNewDelta = cNsOtherNew - pVCpu->tm.s.cNsOtherStat;
     246        if (cNsOtherNewDelta > 0)
     247            STAM_REL_COUNTER_ADD(&pVCpu->tm.s.StatNsOther, (uint64_t)cNsOtherNewDelta);
     248# endif
     249
     250        pVCpu->tm.s.cNsTotalStat = cNsTotalNew;
     251        pVCpu->tm.s.cNsOtherStat = cNsOtherNew;
     252    }
     253
    211254#endif
    212255}
     
    228271
    229272#ifndef VBOX_WITHOUT_NS_ACCOUNTING
    230     pVCpu->tm.s.u64NsTsStartHalting = RTTimeNanoTS();
     273    pVCpu->tm.s.nsStartHalting = RTTimeNanoTS();
     274    pVCpu->tm.s.fHalting       = true;
    231275#endif
    232276
     
    257301#ifndef VBOX_WITHOUT_NS_ACCOUNTING
    258302    uint64_t const u64NsTs        = RTTimeNanoTS();
    259     uint64_t const cNsTotalNew    = u64NsTs - pVCpu->tm.s.u64NsTsStartTotal;
    260     uint64_t const cNsHaltedDelta = u64NsTs - pVCpu->tm.s.u64NsTsStartHalting;
     303    uint64_t const cNsTotalNew    = u64NsTs - pVCpu->tm.s.nsStartTotal;
     304    uint64_t const cNsHaltedDelta = u64NsTs - pVCpu->tm.s.nsStartHalting;
    261305    uint64_t const cNsHaltedNew   = pVCpu->tm.s.cNsHalted + cNsHaltedDelta;
    262306    uint64_t const cNsOtherNew    = cNsTotalNew - pVCpu->tm.s.cNsExecuting - cNsHaltedNew;
    263307
     308    uint32_t uGen = ASMAtomicIncU32(&pVCpu->tm.s.uTimesGen); Assert(uGen & 1);
     309    pVCpu->tm.s.fHalting     = false;
     310    pVCpu->tm.s.fUpdateStats = false;
     311    pVCpu->tm.s.cNsHalted    = cNsHaltedNew;
     312    pVCpu->tm.s.cPeriodsHalted++;
     313    ASMAtomicWriteU32(&pVCpu->tm.s.uTimesGen, (uGen | 1) + 1);
     314
    264315# if defined(VBOX_WITH_STATISTICS) || defined(VBOX_WITH_NS_ACCOUNTING_STATS)
    265316    STAM_REL_PROFILE_ADD_PERIOD(&pVCpu->tm.s.StatNsHalted, cNsHaltedDelta);
    266     STAM_REL_COUNTER_ADD(&pVCpu->tm.s.StatNsTotal, cNsTotalNew - pVCpu->tm.s.cNsTotal);
    267     int64_t  const cNsOtherNewDelta  = cNsOtherNew - pVCpu->tm.s.cNsOther;
     317    STAM_REL_COUNTER_ADD(&pVCpu->tm.s.StatNsTotal, cNsTotalNew - pVCpu->tm.s.cNsTotalStat);
     318    int64_t const cNsOtherNewDelta = cNsOtherNew - pVCpu->tm.s.cNsOtherStat;
    268319    if (cNsOtherNewDelta > 0)
    269         STAM_REL_PROFILE_ADD_PERIOD(&pVCpu->tm.s.StatNsOther, cNsOtherNewDelta); /* (the period before halting) */
     320        STAM_REL_COUNTER_ADD(&pVCpu->tm.s.StatNsOther, (uint64_t)cNsOtherNewDelta);
    270321# endif
    271 
    272     uint32_t uGen = ASMAtomicIncU32(&pVCpu->tm.s.uTimesGen); Assert(uGen & 1);
    273     pVCpu->tm.s.cNsHalted = cNsHaltedNew;
    274     pVCpu->tm.s.cNsTotal  = cNsTotalNew;
    275     pVCpu->tm.s.cNsOther  = cNsOtherNew;
    276     pVCpu->tm.s.cPeriodsHalted++;
    277     ASMAtomicWriteU32(&pVCpu->tm.s.uTimesGen, (uGen | 1) + 1);
     322    pVCpu->tm.s.cNsTotalStat = cNsTotalNew;
     323    pVCpu->tm.s.cNsOtherStat = cNsOtherNew;
    278324#endif
    279325}
  • trunk/src/VBox/VMM/VMMR3/TM.cpp

    r87626 r87748  
    801801#ifndef VBOX_WITHOUT_NS_ACCOUNTING
    802802# if defined(VBOX_WITH_STATISTICS) || defined(VBOX_WITH_NS_ACCOUNTING_STATS)
    803         STAMR3RegisterF(pVM, &pVCpu->tm.s.StatNsTotal,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_NS,               "Resettable: Total CPU run time.",   "/TM/CPU/%02u", i);
    804         STAMR3RegisterF(pVM, &pVCpu->tm.s.StatNsExecuting,   STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent executing guest code.",    "/TM/CPU/%02u/PrfExecuting", i);
    805         STAMR3RegisterF(pVM, &pVCpu->tm.s.StatNsExecLong,    STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent executing guest code - long hauls.",    "/TM/CPU/%02u/PrfExecLong", i);
    806         STAMR3RegisterF(pVM, &pVCpu->tm.s.StatNsExecShort,   STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent executing guest code - short stretches.",    "/TM/CPU/%02u/PrfExecShort", i);
    807         STAMR3RegisterF(pVM, &pVCpu->tm.s.StatNsExecTiny,    STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent executing guest code - tiny bits.",    "/TM/CPU/%02u/PrfExecTiny", i);
    808         STAMR3RegisterF(pVM, &pVCpu->tm.s.StatNsHalted,      STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent halted.",                  "/TM/CPU/%02u/PrfHalted", i);
    809         STAMR3RegisterF(pVM, &pVCpu->tm.s.StatNsOther,       STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent in the VMM or preempted.", "/TM/CPU/%02u/PrfOther", i);
     803        STAMR3RegisterF(pVM, &pVCpu->tm.s.StatNsTotal,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_NS,               "Resettable: Total CPU run time.",                                 "/TM/CPU/%02u", i);
     804        STAMR3RegisterF(pVM, &pVCpu->tm.s.StatNsExecuting,   STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent executing guest code.",                    "/TM/CPU/%02u/PrfExecuting", i);
     805        STAMR3RegisterF(pVM, &pVCpu->tm.s.StatNsExecLong,    STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent executing guest code - long hauls.",       "/TM/CPU/%02u/PrfExecLong", i);
     806        STAMR3RegisterF(pVM, &pVCpu->tm.s.StatNsExecShort,   STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent executing guest code - short stretches.",  "/TM/CPU/%02u/PrfExecShort", i);
     807        STAMR3RegisterF(pVM, &pVCpu->tm.s.StatNsExecTiny,    STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent executing guest code - tiny bits.",        "/TM/CPU/%02u/PrfExecTiny", i);
     808        STAMR3RegisterF(pVM, &pVCpu->tm.s.StatNsHalted,      STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent halted.",                                  "/TM/CPU/%02u/PrfHalted", i);
     809        STAMR3RegisterF(pVM, &pVCpu->tm.s.StatNsOther,       STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent in the VMM or preempted.",                 "/TM/CPU/%02u/PrfOther", i);
    810810# endif
    811         STAMR3RegisterF(pVM, &pVCpu->tm.s.cNsTotal,              STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_NS,    "Total CPU run time.",                          "/TM/CPU/%02u/cNsTotal", i);
     811        STAMR3RegisterF(pVM, &pVCpu->tm.s.cNsTotalStat,          STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_NS,    "Total CPU run time.",                          "/TM/CPU/%02u/cNsTotal", i);
    812812        STAMR3RegisterF(pVM, &pVCpu->tm.s.cNsExecuting,          STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_NS,    "Time spent executing guest code.",             "/TM/CPU/%02u/cNsExecuting", i);
    813813        STAMR3RegisterF(pVM, &pVCpu->tm.s.cNsHalted,             STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_NS,    "Time spent halted.",                           "/TM/CPU/%02u/cNsHalted", i);
    814         STAMR3RegisterF(pVM, &pVCpu->tm.s.cNsOther,              STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_NS,    "Time spent in the VMM or preempted.",          "/TM/CPU/%02u/cNsOther", i);
     814        STAMR3RegisterF(pVM, &pVCpu->tm.s.cNsOtherStat,          STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_NS,    "Time spent in the VMM or preempted.",          "/TM/CPU/%02u/cNsOther", i);
    815815        STAMR3RegisterF(pVM, &pVCpu->tm.s.cPeriodsExecuting,     STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Times executed guest code.",                   "/TM/CPU/%02u/cPeriodsExecuting", i);
    816816        STAMR3RegisterF(pVM, &pVCpu->tm.s.cPeriodsHalted,        STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Times halted.",                                "/TM/CPU/%02u/cPeriodsHalted", i);
     
    30223022#ifndef VBOX_WITHOUT_NS_ACCOUNTING
    30233023    /*
    3024      * Update cNsTotal.
    3025      */
     3024     * Update cNsTotal and stats.
     3025     */
     3026    Assert(!pVCpu->tm.s.fSuspended);
     3027    uint64_t const cNsTotalNew = RTTimeNanoTS() - pVCpu->tm.s.nsStartTotal;
     3028    uint64_t const cNsOtherNew = cNsTotalNew - pVCpu->tm.s.cNsExecuting - pVCpu->tm.s.cNsHalted;
     3029
     3030# if defined(VBOX_WITH_STATISTICS) || defined(VBOX_WITH_NS_ACCOUNTING_STATS)
     3031    STAM_REL_COUNTER_ADD(&pVCpu->tm.s.StatNsTotal, cNsTotalNew - pVCpu->tm.s.cNsTotalStat);
     3032    int64_t const cNsOtherNewDelta = cNsOtherNew - pVCpu->tm.s.cNsOtherStat;
     3033    if (cNsOtherNewDelta > 0)
     3034        STAM_REL_COUNTER_ADD(&pVCpu->tm.s.StatNsOther, (uint64_t)cNsOtherNewDelta);
     3035# endif
     3036
    30263037    uint32_t uGen = ASMAtomicIncU32(&pVCpu->tm.s.uTimesGen); Assert(uGen & 1);
    3027     pVCpu->tm.s.cNsTotal = RTTimeNanoTS() - pVCpu->tm.s.u64NsTsStartTotal;
    3028     pVCpu->tm.s.cNsOther = pVCpu->tm.s.cNsTotal - pVCpu->tm.s.cNsExecuting - pVCpu->tm.s.cNsHalted;
     3038    pVCpu->tm.s.nsStartTotal = cNsTotalNew;
     3039    pVCpu->tm.s.fSuspended   = true;
     3040    pVCpu->tm.s.cNsTotalStat = cNsTotalNew;
     3041    pVCpu->tm.s.cNsOtherStat = cNsOtherNew;
    30293042    ASMAtomicWriteU32(&pVCpu->tm.s.uTimesGen, (uGen | 1) + 1);
    30303043#endif
     
    30523065     * the two calls below fail.
    30533066     */
    3054     pVCpu->tm.s.u64NsTsStartTotal = RTTimeNanoTS() - pVCpu->tm.s.cNsTotal;
     3067    uint32_t uGen = ASMAtomicIncU32(&pVCpu->tm.s.uTimesGen); Assert(uGen & 1);
     3068    pVCpu->tm.s.nsStartTotal = RTTimeNanoTS() - pVCpu->tm.s.nsStartTotal;
     3069    pVCpu->tm.s.fSuspended   = false;
     3070    ASMAtomicWriteU32(&pVCpu->tm.s.uTimesGen, (uGen | 1) + 1);
    30553071#endif
    30563072
     
    32263242
    32273243
     3244#if 0 /* unused - needs a little updating after @bugref{9941}*/
    32283245/**
    32293246 * Gets the performance information for one virtual CPU as seen by the VMM.
     
    32963313#endif
    32973314}
     3315#endif /* unused */
    32983316
    32993317
     
    34453463        /* Try get a stable data set. */
    34463464        uint32_t    cTries       = 3;
     3465        uint64_t    nsNow        = RTTimeNanoTS();
    34473466        uint32_t    uTimesGen    = ASMAtomicReadU32(&pVCpu->tm.s.uTimesGen);
    3448         uint64_t    cNsTotal     = pVCpu->tm.s.cNsTotal;
     3467        bool        fSuspended   = pVCpu->tm.s.fSuspended;
     3468        uint64_t    nsStartTotal = pVCpu->tm.s.nsStartTotal;
    34493469        uint64_t    cNsExecuting = pVCpu->tm.s.cNsExecuting;
    34503470        uint64_t    cNsHalted    = pVCpu->tm.s.cNsHalted;
     
    34553475                break;
    34563476            ASMNopPause();
     3477            nsNow        = RTTimeNanoTS();
    34573478            uTimesGen    = ASMAtomicReadU32(&pVCpu->tm.s.uTimesGen);
    3458             cNsTotal     = pVCpu->tm.s.cNsTotal;
     3479            fSuspended   = pVCpu->tm.s.fSuspended;
     3480            nsStartTotal = pVCpu->tm.s.nsStartTotal;
    34593481            cNsExecuting = pVCpu->tm.s.cNsExecuting;
    34603482            cNsHalted    = pVCpu->tm.s.cNsHalted;
     
    34623484
    34633485        /* Totals */
     3486        uint64_t cNsTotal = fSuspended ? nsStartTotal : nsNow - nsStartTotal;
    34643487        cNsTotalAll     += cNsTotal;
    34653488        cNsExecutingAll += cNsExecuting;
     
    34683491        /* Calc the PCTs and update the state. */
    34693492        tmR3CpuLoadTimerMakeUpdate(&pVCpu->tm.s.CpuLoad, cNsTotal, cNsExecuting, cNsHalted);
     3493
     3494        /* Tell the VCpu to update the other and total stat members. */
     3495        ASMAtomicWriteBool(&pVCpu->tm.s.fUpdateStats, true);
    34703496    }
    34713497
  • trunk/src/VBox/VMM/include/TMInternal.h

    r87626 r87748  
    716716typedef struct TMCPU
    717717{
    718     /** Offset to the VMCPU structure.
    719      * See TMCPU2VM(). */
    720     RTUINT                      offVMCPU;
    721 
    722718    /** CPU timestamp ticking enabled indicator (bool). (RDTSC) */
    723719    bool                        fTSCTicking;
    724     bool                        afAlignment0[3]; /**< alignment padding */
    725 
     720    bool                        afAlignment0[7]; /**< alignment padding */
    726721    /** The offset between the host tick (TSC/virtual depending on the TSC mode) and
    727722     *  the guest tick. */
    728723    uint64_t                    offTSCRawSrc;
    729 
    730724    /** The guest TSC when fTicking is cleared. */
    731725    uint64_t                    u64TSC;
    732 
    733726    /** The last seen TSC by the guest. */
    734727    uint64_t                    u64TSCLastSeen;
    735728
    736729#ifndef VBOX_WITHOUT_NS_ACCOUNTING
     730    /** Align  */
     731    uint64_t                    au64Alignment[4];
     732
     733    /** @name Core accounting data.  Must be cache-line aligned.
     734     * @{ */
     735    /** The cNsXXX generation. */
     736    uint32_t volatile           uTimesGen;
     737    /** Set if executing (between TMNotifyStartOfExecution and
     738     *  TMNotifyEndOfExecution). */
     739    bool volatile               fExecuting;
     740    /** Set if halting (between TMNotifyStartOfHalt and TMNotifyEndOfHalt). */
     741    bool volatile               fHalting;
     742    /** Set if we're suspended and u64NsTsStartTotal is to be cNsTotal. */
     743    bool volatile               fSuspended;
     744    /** Set by the timer callback to trigger updating of statistics in
     745     *  TMNotifyEndOfExecution. */
     746    bool volatile               fUpdateStats;
    737747    /** The nanosecond timestamp of the CPU start or resume.
    738748     * This is recalculated when the VM is started so that
    739749     * cNsTotal = RTTimeNanoTS() - u64NsTsStartCpu. */
    740     uint64_t                    u64NsTsStartTotal;
    741     /** The nanosecond timestamp of the last start-execute notification. */
    742     uint64_t                    u64NsTsStartExecuting;
    743     /** The nanosecond timestamp of the last start-halt notification. */
    744     uint64_t                    u64NsTsStartHalting;
    745     /** The cNsXXX generation. */
    746     uint32_t volatile           uTimesGen;
    747     /** Explicit alignment padding.  */
    748     uint32_t                    u32Alignment;
    749     /** The number of nanoseconds total run time.
    750      * @remarks This is updated when cNsExecuting and cNsHalted are updated. */
    751     uint64_t                    cNsTotal;
     750    uint64_t                    nsStartTotal;
     751    /** The TSC of the last start-execute notification. */
     752    uint64_t                    uTscStartExecuting;
    752753    /** The number of nanoseconds spent executing. */
    753754    uint64_t                    cNsExecuting;
     755    /** The number of guest execution runs. */
     756    uint64_t                    cPeriodsExecuting;
     757    /** The nanosecond timestamp of the last start-halt notification. */
     758    uint64_t                    nsStartHalting;
    754759    /** The number of nanoseconds being halted. */
    755760    uint64_t                    cNsHalted;
    756     /** The number of nanoseconds spent on other things.
    757      * @remarks This is updated when cNsExecuting and cNsHalted are updated. */
    758     uint64_t                    cNsOther;
    759761    /** The number of halts. */
    760762    uint64_t                    cPeriodsHalted;
    761     /** The number of guest execution runs. */
    762     uint64_t                    cPeriodsExecuting;
     763    /** @} */
     764
    763765# if defined(VBOX_WITH_STATISTICS) || defined(VBOX_WITH_NS_ACCOUNTING_STATS)
    764     /** Resettable version of cNsTotal. */
    765     STAMCOUNTER                 StatNsTotal;
    766766    /** Resettable version of cNsExecuting. */
    767767    STAMPROFILE                 StatNsExecuting;
    768768    /** Long execution intervals. */
    769769    STAMPROFILE                 StatNsExecLong;
    770     /** Short execution intervals . */
     770    /** Short execution intervals. */
    771771    STAMPROFILE                 StatNsExecShort;
    772     /** Tiny execution intervals . */
     772    /** Tiny execution intervals. */
    773773    STAMPROFILE                 StatNsExecTiny;
    774774    /** Resettable version of cNsHalted. */
    775775    STAMPROFILE                 StatNsHalted;
    776     /** Resettable version of cNsOther. */
    777     STAMPROFILE                 StatNsOther;
     776
     777    /** Resettable copy of version of cNsOtherStat.
     778    * @note Only updated after halting. */
     779    STAMCOUNTER                 StatNsOther;
     780    /** Resettable copy of cNsTotalStat.
     781     * @note Only updated after halting. */
     782    STAMCOUNTER                 StatNsTotal;
    778783# endif
     784    /** The time not spent executing or halted.
     785     * @note Only updated after halting and after the timer runs. */
     786    uint64_t                    cNsOtherStat;
     787    /** Reasonably up to date total run time value.
     788     * @note Only updated after halting and after the timer runs. */
     789    uint64_t                    cNsTotalStat;
    779790
    780791    /** CPU load state for this virtual CPU (tmR3CpuLoadTimer). */
     
    782793#endif
    783794} TMCPU;
     795#ifndef VBOX_WITHOUT_NS_ACCOUNTING
     796AssertCompileMemberAlignment(TMCPU, uTimesGen, 64);
     797# if defined(VBOX_WITH_STATISTICS) || defined(VBOX_WITH_NS_ACCOUNTING_STATS)
     798AssertCompileMemberAlignment(TMCPU, StatNsExecuting, 64);
     799# else
     800AssertCompileMemberAlignment(TMCPU, cNsOtherStat, 64);
     801# endif
     802#endif
    784803/** Pointer to TM VMCPU instance data. */
    785804typedef TMCPU *PTMCPU;
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