예제 #1
0
STDMETHODIMP Guest::InternalGetStatistics(ULONG *aCpuUser, ULONG *aCpuKernel, ULONG *aCpuIdle,
                                          ULONG *aMemTotal, ULONG *aMemFree, ULONG *aMemBalloon, ULONG *aMemShared,
                                          ULONG *aMemCache, ULONG *aPageTotal,
                                          ULONG *aMemAllocTotal, ULONG *aMemFreeTotal, ULONG *aMemBalloonTotal, ULONG *aMemSharedTotal)
{
    CheckComArgOutPointerValid(aCpuUser);
    CheckComArgOutPointerValid(aCpuKernel);
    CheckComArgOutPointerValid(aCpuIdle);
    CheckComArgOutPointerValid(aMemTotal);
    CheckComArgOutPointerValid(aMemFree);
    CheckComArgOutPointerValid(aMemBalloon);
    CheckComArgOutPointerValid(aMemShared);
    CheckComArgOutPointerValid(aMemCache);
    CheckComArgOutPointerValid(aPageTotal);
    CheckComArgOutPointerValid(aMemAllocTotal);
    CheckComArgOutPointerValid(aMemFreeTotal);
    CheckComArgOutPointerValid(aMemBalloonTotal);
    CheckComArgOutPointerValid(aMemSharedTotal);

    AutoCaller autoCaller(this);
    if (FAILED(autoCaller.rc())) return autoCaller.rc();

    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);

    *aCpuUser    = mCurrentGuestStat[GUESTSTATTYPE_CPUUSER];
    *aCpuKernel  = mCurrentGuestStat[GUESTSTATTYPE_CPUKERNEL];
    *aCpuIdle    = mCurrentGuestStat[GUESTSTATTYPE_CPUIDLE];
    *aMemTotal   = mCurrentGuestStat[GUESTSTATTYPE_MEMTOTAL] * (_4K/_1K);     /* page (4K) -> 1KB units */
    *aMemFree    = mCurrentGuestStat[GUESTSTATTYPE_MEMFREE] * (_4K/_1K);       /* page (4K) -> 1KB units */
    *aMemBalloon = mCurrentGuestStat[GUESTSTATTYPE_MEMBALLOON] * (_4K/_1K); /* page (4K) -> 1KB units */
    *aMemCache   = mCurrentGuestStat[GUESTSTATTYPE_MEMCACHE] * (_4K/_1K);     /* page (4K) -> 1KB units */
    *aPageTotal  = mCurrentGuestStat[GUESTSTATTYPE_PAGETOTAL] * (_4K/_1K);   /* page (4K) -> 1KB units */

    /* MUST release all locks before calling any PGM statistics queries,
     * as they are executed by EMT and that might deadlock us by VMM device
     * activity which waits for the Guest object lock. */
    alock.release();
    Console::SafeVMPtr pVM (mParent);
    if (pVM.isOk())
    {
        uint64_t uFreeTotal, uAllocTotal, uBalloonedTotal, uSharedTotal;
        *aMemFreeTotal = 0;
        int rc = PGMR3QueryGlobalMemoryStats(pVM.raw(), &uAllocTotal, &uFreeTotal, &uBalloonedTotal, &uSharedTotal);
        AssertRC(rc);
        if (rc == VINF_SUCCESS)
        {
            *aMemAllocTotal   = (ULONG)(uAllocTotal / _1K);  /* bytes -> KB */
            *aMemFreeTotal    = (ULONG)(uFreeTotal / _1K);
            *aMemBalloonTotal = (ULONG)(uBalloonedTotal / _1K);
            *aMemSharedTotal  = (ULONG)(uSharedTotal / _1K);
        }
        else
            return E_FAIL;

        /* Query the missing per-VM memory statistics. */
        *aMemShared  = 0;
        uint64_t uTotalMem, uPrivateMem, uSharedMem, uZeroMem;
        rc = PGMR3QueryMemoryStats(pVM.raw(), &uTotalMem, &uPrivateMem, &uSharedMem, &uZeroMem);
        if (rc == VINF_SUCCESS)
        {
            *aMemShared = (ULONG)(uSharedMem / _1K);
        }
        else
            return E_FAIL;
    }
    else
    {
        *aMemAllocTotal   = 0;
        *aMemFreeTotal    = 0;
        *aMemBalloonTotal = 0;
        *aMemSharedTotal  = 0;
        *aMemShared       = 0;
        return E_FAIL;
    }

    return S_OK;
}
예제 #2
0
void Guest::updateStats(uint64_t iTick)
{
    uint64_t uFreeTotal, uAllocTotal, uBalloonedTotal, uSharedTotal;
    uint64_t uTotalMem, uPrivateMem, uSharedMem, uZeroMem;

    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);

    ULONG aGuestStats[GUESTSTATTYPE_MAX];
    RT_ZERO(aGuestStats);
    ULONG validStats = mGuestValidStats;
    /* Check if we have anything to report */
    if (validStats)
    {
        mGuestValidStats = pm::GUESTSTATMASK_NONE;
        memcpy(aGuestStats, mCurrentGuestStat, sizeof(aGuestStats));
    }
    alock.release();
    /*
     * Calling SessionMachine may take time as the object resides in VBoxSVC
     * process. This is why we took a snapshot of currently collected stats
     * and released the lock.
     */
    uFreeTotal      = 0;
    uAllocTotal     = 0;
    uBalloonedTotal = 0;
    uSharedTotal    = 0;
    uTotalMem       = 0;
    uPrivateMem     = 0;
    uSharedMem      = 0;
    uZeroMem        = 0;

    Console::SafeVMPtr pVM (mParent);
    if (pVM.isOk())
    {
        int rc;

        /*
         * There is no point in collecting VM shared memory if other memory
         * statistics are not available yet. Or is it?
         */
        if (validStats)
        {
            /* Query the missing per-VM memory statistics. */
            rc = PGMR3QueryMemoryStats(pVM.raw(), &uTotalMem, &uPrivateMem, &uSharedMem, &uZeroMem);
            if (rc == VINF_SUCCESS)
            {
                validStats |= pm::GUESTSTATMASK_MEMSHARED;
            }
        }

        if (mCollectVMMStats)
        {
            rc = PGMR3QueryGlobalMemoryStats(pVM.raw(), &uAllocTotal, &uFreeTotal, &uBalloonedTotal, &uSharedTotal);
            AssertRC(rc);
            if (rc == VINF_SUCCESS)
            {
                validStats |= pm::GUESTSTATMASK_ALLOCVMM|pm::GUESTSTATMASK_FREEVMM|
                    pm::GUESTSTATMASK_BALOONVMM|pm::GUESTSTATMASK_SHAREDVMM;
            }
        }

    }

    mParent->reportGuestStatistics(validStats,
                                   aGuestStats[GUESTSTATTYPE_CPUUSER],
                                   aGuestStats[GUESTSTATTYPE_CPUKERNEL],
                                   aGuestStats[GUESTSTATTYPE_CPUIDLE],
                                   /* Convert the units for RAM usage stats: page (4K) -> 1KB units */
                                   mCurrentGuestStat[GUESTSTATTYPE_MEMTOTAL] * (_4K/_1K),
                                   mCurrentGuestStat[GUESTSTATTYPE_MEMFREE] * (_4K/_1K),
                                   mCurrentGuestStat[GUESTSTATTYPE_MEMBALLOON] * (_4K/_1K),
                                   (ULONG)(uSharedMem / _1K), /* bytes -> KB */
                                   mCurrentGuestStat[GUESTSTATTYPE_MEMCACHE] * (_4K/_1K),
                                   mCurrentGuestStat[GUESTSTATTYPE_PAGETOTAL] * (_4K/_1K),
                                   (ULONG)(uAllocTotal / _1K), /* bytes -> KB */
                                   (ULONG)(uFreeTotal / _1K),
                                   (ULONG)(uBalloonedTotal / _1K),
                                   (ULONG)(uSharedTotal / _1K));
}