VirtualBox

Changeset 80157 in vbox


Ignore:
Timestamp:
Aug 6, 2019 1:55:27 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
132598
Message:

VMM/TM: 'info cpuload' improvements.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/TM.cpp

    r80142 r80157  
    145145
    146146#include <VBox/vmm/pdmdev.h>
     147#include <VBox/log.h>
    147148#include <VBox/param.h>
    148149#include <VBox/err.h>
    149150
    150 #include <VBox/log.h>
    151151#include <iprt/asm.h>
    152152#include <iprt/asm-math.h>
    153153#include <iprt/assert.h>
     154#include <iprt/env.h>
    154155#include <iprt/file.h>
     156#include <iprt/getopt.h>
     157#include <iprt/semaphore.h>
     158#include <iprt/string.h>
    155159#include <iprt/thread.h>
    156160#include <iprt/time.h>
    157161#include <iprt/timer.h>
    158 #include <iprt/semaphore.h>
    159 #include <iprt/string.h>
    160 #include <iprt/env.h>
    161162
    162163#include "TMInline.h"
     
    187188static DECLCALLBACK(void)   tmR3TimerInfoActive(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
    188189static DECLCALLBACK(void)   tmR3InfoClocks(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
    189 static DECLCALLBACK(void)   tmR3InfoCpuLoad(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
     190static DECLCALLBACK(void)   tmR3InfoCpuLoad(PVM pVM, PCDBGFINFOHLP pHlp, int cArgs, char **papszArgs);
    190191static DECLCALLBACK(VBOXSTRICTRC) tmR3CpuTickParavirtDisable(PVM pVM, PVMCPU pVCpu, void *pvData);
    191192static const char *         tmR3GetTSCModeName(PVM pVM);
     
    855856    DBGFR3InfoRegisterInternalEx(pVM, "activetimers", "Dumps active all timers. No arguments.",   tmR3TimerInfoActive,  DBGFINFO_FLAGS_RUN_ON_EMT);
    856857    DBGFR3InfoRegisterInternalEx(pVM, "clocks",       "Display the time of the various clocks.",  tmR3InfoClocks,       DBGFINFO_FLAGS_RUN_ON_EMT);
    857     DBGFR3InfoRegisterInternalEx(pVM, "cpuload",      "Display the CPU load stats.",              tmR3InfoCpuLoad,      0);
     858    DBGFR3InfoRegisterInternalArgv(pVM, "cpuload",    "Display the CPU load stats.",              tmR3InfoCpuLoad,      0);
    858859
    859860    return VINF_SUCCESS;
     
    37603761
    37613762/**
    3762  * @callback_function_impl{}
    3763  */
    3764 static DECLCALLBACK(void) tmR3InfoCpuLoad(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs)
    3765 {
     3763 * Helper for tmR3InfoCpuLoad that adjust @a uPct to the given graph width.
     3764 */
     3765DECLINLINE(size_t) tmR3InfoCpuLoadAdjustWidth(size_t uPct, size_t cchWidth)
     3766{
     3767    if (cchWidth != 100)
     3768        uPct = (uPct + 0.5) * (cchWidth / 100.0);
     3769    return uPct;
     3770}
     3771
     3772
     3773/**
     3774 * @callback_function_impl{FNDBGFINFOARGVINT}
     3775 */
     3776static DECLCALLBACK(void) tmR3InfoCpuLoad(PVM pVM, PCDBGFINFOHLP pHlp, int cArgs, char **papszArgs)
     3777{
     3778    char szTmp[1024];
     3779
    37663780    /*
    37673781     * Parse arguments.
    37683782     */
    3769     PTMCPULOADSTATE pState   = &pVM->tm.s.CpuLoad;
    3770     uint32_t        cPeriods = 60;
    3771     //uint32_t        cchWidth = 100;
    3772 
    3773 
    3774     RT_NOREF(pszArgs); /** @todo */
     3783    PTMCPULOADSTATE pState      = &pVM->tm.s.CpuLoad;
     3784    VMCPUID         idCpu       = VMCPUID_ALL;
     3785    bool            fExpGraph   = true;
     3786    uint32_t        cchWidth    = 100;
     3787    uint32_t        cPeriods    = RT_ELEMENTS(pState->aHistory);
     3788    uint32_t        cRows       = 60;
     3789
     3790    static const RTGETOPTDEF s_aOptions[] =
     3791    {
     3792        { "cpu",            'c',    RTGETOPT_REQ_UINT32 },
     3793        { "periods",        'p',    RTGETOPT_REQ_UINT32 },
     3794        { "linear",         'l',    RTGETOPT_REQ_NOTHING },
     3795        { "rows",           'r',    RTGETOPT_REQ_UINT32 },
     3796        { "width",          'w',    RTGETOPT_REQ_UINT32 },
     3797        { "exp",            'x',    RTGETOPT_REQ_NOTHING },
     3798        { "exponential",    'x',    RTGETOPT_REQ_NOTHING },
     3799    };
     3800
     3801    RTGETOPTSTATE State;
     3802    int rc = RTGetOptInit(&State, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
     3803    AssertRC(rc);
     3804
     3805    RTGETOPTUNION ValueUnion;
     3806    while ((rc = RTGetOpt(&State, &ValueUnion)) != 0)
     3807    {
     3808        switch (rc)
     3809        {
     3810            case 'c':
     3811                if (ValueUnion.u32 < pVM->cCpus)
     3812                {
     3813                    pState = &pVM->aCpus[ValueUnion.u32].tm.s.CpuLoad;
     3814                    idCpu  = ValueUnion.u32;
     3815                }
     3816                else
     3817                {
     3818                    pState = &pVM->tm.s.CpuLoad;
     3819                    idCpu  = VMCPUID_ALL;
     3820                }
     3821                break;
     3822            case 'p':
     3823                cPeriods = RT_MIN(RT_MAX(ValueUnion.u32, 1), RT_ELEMENTS(pState->aHistory));
     3824                break;
     3825            case 'w':
     3826                cchWidth = RT_MIN(RT_MAX(ValueUnion.u32, 10), sizeof(szTmp) - 32);
     3827                break;
     3828            case 'x':
     3829                fExpGraph = true;
     3830                break;
     3831            case 'l':
     3832                fExpGraph = false;
     3833                break;
     3834            case 'r':
     3835                cRows = RT_MIN(RT_MAX(ValueUnion.u32, 5), RT_ELEMENTS(pState->aHistory));
     3836                break;
     3837            default:
     3838                pHlp->pfnGetOptError(pHlp, rc, &ValueUnion, &State);
     3839                return;
     3840        }
     3841    }
    37753842
    37763843    /*
     
    37823849    if (cPeriods > 0)
    37833850    {
    3784         size_t iHistory = (pState->idxHistory - cPeriods) % RT_ELEMENTS(pState->aHistory);
     3851        /*
     3852         * Figure number of periods per chunk.  We can either do this in a linear
     3853         * fashion or a exponential fashion that compresses old history more.
     3854         */
     3855        size_t cPeriodsPerRow = 1;
     3856        if (cRows < cPeriods)
     3857        {
     3858            if (fExpGraph)
     3859            {
     3860                /* The last 30 seconds or half of the rows are 1:1, the other part
     3861                   is in increasing period counts.  Code is a little simple but seems
     3862                   to do the job most of the time, which is all I have time now. */
     3863                size_t cPeriodsOneToOne = RT_MIN(30, cRows / 2);
     3864                size_t cRestRows        = cRows    - cPeriodsOneToOne;
     3865                size_t cRestPeriods     = cPeriods - cPeriodsOneToOne;
     3866
     3867                size_t cPeriodsInWindow = 0;
     3868                for (cPeriodsPerRow = 0; cPeriodsPerRow <= cRestRows && cPeriodsInWindow < cRestPeriods; cPeriodsPerRow++)
     3869                    cPeriodsInWindow += cPeriodsPerRow + 1;
     3870
     3871                size_t iLower = 1;
     3872                while (cPeriodsInWindow < cRestPeriods)
     3873                {
     3874                    cPeriodsPerRow++;
     3875                    cPeriodsInWindow += cPeriodsPerRow;
     3876                    cPeriodsInWindow -= iLower;
     3877                    iLower++;
     3878                }
     3879            }
     3880            else
     3881            {
     3882                cPeriodsPerRow   = (cPeriods + cRows / 2) / cRows;
     3883            }
     3884        }
     3885
     3886        /*
     3887         * Do the work.
     3888         */
     3889        size_t cPctExecuting       = 0;
     3890        size_t cPctOther           = 0;
     3891        size_t cPeriodsAccumulated = 0;
     3892
     3893        size_t cRowsLeft = cRows;
     3894        size_t iHistory  = (pState->idxHistory - cPeriods) % RT_ELEMENTS(pState->aHistory);
    37853895        while (cPeriods-- > 0)
    37863896        {
     
    37883898            if (iHistory >= RT_ELEMENTS(pState->aHistory))
    37893899                iHistory = 0;
    3790             char   szTmp[1024];
    3791             size_t offTmp = 0;
    3792             size_t i      = pState->aHistory[iHistory].cPctExecuting;
    3793             while (i-- > 0)
    3794                 szTmp[offTmp++] = '#';
    3795             i = pState->aHistory[iHistory].cPctOther;
    3796             while (i-- > 0)
    3797                 szTmp[offTmp++] = 'O';
    3798             szTmp[offTmp] = '\0';
    3799             pHlp->pfnPrintf(pHlp, "%2ds: %s\n", cPeriods, szTmp);
     3900
     3901            cPctExecuting        += pState->aHistory[iHistory].cPctExecuting;
     3902            cPctOther            += pState->aHistory[iHistory].cPctOther;
     3903            cPeriodsAccumulated  += 1;
     3904            if (   cPeriodsAccumulated >= cPeriodsPerRow
     3905                || cPeriods < cRowsLeft)
     3906            {
     3907                /*
     3908                 * Format and output the line.
     3909                 */
     3910                size_t offTmp = 0;
     3911                size_t i      = tmR3InfoCpuLoadAdjustWidth(cPctExecuting / cPeriodsAccumulated, cchWidth);
     3912                while (i-- > 0)
     3913                    szTmp[offTmp++] = '#';
     3914                i = tmR3InfoCpuLoadAdjustWidth(cPctOther / cPeriodsAccumulated, cchWidth);
     3915                while (i-- > 0)
     3916                    szTmp[offTmp++] = 'O';
     3917                szTmp[offTmp] = '\0';
     3918
     3919                cRowsLeft--;
     3920                pHlp->pfnPrintf(pHlp, "%3zus: %s\n", cPeriods + cPeriodsAccumulated / 2, szTmp);
     3921
     3922                /* Reset the state: */
     3923                cPctExecuting       = 0;
     3924                cPctOther           = 0;
     3925                cPeriodsAccumulated = 0;
     3926                if (cPeriodsPerRow > 1)
     3927                    cPeriodsPerRow--;
     3928            }
    38003929        }
    38013930        pHlp->pfnPrintf(pHlp, "  (#=guest, O=VMM overhead)\n");
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