VirtualBox

Changeset 85574 in vbox for trunk/src/VBox/Main/src-server


Ignore:
Timestamp:
Jul 31, 2020 12:45:16 PM (4 years ago)
Author:
vboxsync
Message:

Main: Added ISystemProperties::getCPUProfiles.

Location:
trunk/src/VBox/Main/src-server
Files:
1 added
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-server/SystemPropertiesImpl.cpp

    r84978 r85574  
    2323# include "ExtPackManagerImpl.h"
    2424#endif
     25#include "CPUProfileImpl.h"
    2526#include "AutoCaller.h"
    2627#include "Global.h"
     
    4243#include <VBox/settings.h>
    4344#include <VBox/vd.h>
     45#include <VBox/vmm/cpum.h>
    4446
    4547// defines
     
    5052
    5153SystemProperties::SystemProperties()
    52     : mParent(NULL),
    53       m(new settings::SystemProperties)
     54    : mParent(NULL)
     55    , m(new settings::SystemProperties)
     56    , m_fLoadedX86CPUProfiles(false)
    5457{
    5558}
     
    710713    return S_OK;
    711714}
     715
     716HRESULT SystemProperties::getCPUProfiles(CPUArchitecture_T aArchitecture, const com::Utf8Str &aNamePattern,
     717                                         std::vector<ComPtr<ICPUProfile> > &aProfiles)
     718{
     719    /*
     720     * Validate and adjust the architecture.
     721     */
     722    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     723    CPUArchitecture_T enmSecondaryArch = aArchitecture;
     724    bool fLoaded;
     725    switch (aArchitecture)
     726    {
     727        case CPUArchitecture_Any:
     728            aArchitecture = CPUArchitecture_AMD64;
     729            RT_FALL_THROUGH();
     730        case CPUArchitecture_AMD64:
     731            enmSecondaryArch = CPUArchitecture_x86;
     732            RT_FALL_THROUGH();
     733        case CPUArchitecture_x86:
     734            fLoaded = m_fLoadedX86CPUProfiles;
     735            break;
     736        default:
     737            return setError(E_INVALIDARG, tr("Invalid or unsupported architecture value: %d"), aArchitecture);
     738    }
     739
     740    /*
     741     * Do we need to load the profiles?
     742     */
     743    HRESULT hrc;
     744    if (fLoaded)
     745        hrc = S_OK;
     746    else
     747    {
     748        alock.release();
     749        AutoWriteLock alockWrite(this COMMA_LOCKVAL_SRC_POS);
     750
     751        /*
     752         * Translate the architecture to a VMM module handle.
     753         */
     754        const char *pszVMM;
     755        switch (aArchitecture)
     756        {
     757            case CPUArchitecture_AMD64:
     758            case CPUArchitecture_x86:
     759                pszVMM = "VBoxVMM";
     760                fLoaded = m_fLoadedX86CPUProfiles;
     761                break;
     762            default:
     763                AssertFailedReturn(E_INVALIDARG);
     764        }
     765        if (fLoaded)
     766            hrc = S_OK;
     767        else
     768        {
     769            char szPath[RTPATH_MAX];
     770            int vrc = RTPathAppPrivateArch(szPath, sizeof(szPath));
     771            if (RT_SUCCESS(vrc))
     772                vrc = RTPathAppend(szPath, sizeof(szPath), pszVMM);
     773            if (RT_SUCCESS(vrc))
     774                vrc = RTStrCat(szPath, sizeof(szPath), RTLdrGetSuff());
     775            if (RT_SUCCESS(vrc))
     776            {
     777                RTLDRMOD hMod = NIL_RTLDRMOD;
     778                vrc = RTLdrLoad(szPath, &hMod);
     779                if (RT_SUCCESS(vrc))
     780                {
     781                    /*
     782                     * Resolve the CPUMDb APIs we need.
     783                     */
     784                    PFNCPUMDBGETENTRIES      pfnGetEntries
     785                        = (PFNCPUMDBGETENTRIES)RTLdrGetFunction(hMod, "CPUMR3DbGetEntries");
     786                    PFNCPUMDBGETENTRYBYINDEX pfnGetEntryByIndex
     787                        = (PFNCPUMDBGETENTRYBYINDEX)RTLdrGetFunction(hMod, "CPUMR3DbGetEntryByIndex");
     788                    if (pfnGetEntries && pfnGetEntryByIndex)
     789                    {
     790                        size_t const cExistingProfiles = m_llCPUProfiles.size();
     791
     792                        /*
     793                         * Instantate the profiles.
     794                         */
     795                        hrc = S_OK;
     796                        uint32_t const cEntries = pfnGetEntries();
     797                        for (uint32_t i = 0; i < cEntries; i++)
     798                        {
     799                            PCCPUMDBENTRY pDbEntry = pfnGetEntryByIndex(i);
     800                            AssertBreakStmt(pDbEntry, hrc = setError(E_UNEXPECTED, "CPUMR3DbGetEntryByIndex failed for %i", i));
     801
     802                            ComObjPtr<CPUProfile> ptrProfile;
     803                            hrc = ptrProfile.createObject();
     804                            if (SUCCEEDED(hrc))
     805                            {
     806                                hrc = ptrProfile->initFromDbEntry(pDbEntry);
     807                                if (SUCCEEDED(hrc))
     808                                {
     809                                    try
     810                                    {
     811                                        m_llCPUProfiles.push_back(ptrProfile);
     812                                        continue;
     813                                    }
     814                                    catch (std::bad_alloc &)
     815                                    {
     816                                        hrc = E_OUTOFMEMORY;
     817                                    }
     818                                }
     819                            }
     820                            break;
     821                        }
     822
     823                        /*
     824                         * On success update the flag and retake the read lock.
     825                         * If we fail, drop the profiles we added to the list.
     826                         */
     827                        if (SUCCEEDED(hrc))
     828                        {
     829                            switch (aArchitecture)
     830                            {
     831                                case CPUArchitecture_AMD64:
     832                                case CPUArchitecture_x86:
     833                                    m_fLoadedX86CPUProfiles = true;
     834                                    break;
     835                                default:
     836                                    AssertFailedStmt(hrc = E_INVALIDARG);
     837                            }
     838
     839                            alockWrite.release();
     840                            alock.acquire();
     841                        }
     842                        else
     843                            m_llCPUProfiles.resize(cExistingProfiles);
     844                    }
     845                    else
     846                        hrc = setErrorVrc(VERR_SYMBOL_NOT_FOUND,
     847                                          tr("'%s' is missing symbols: CPUMR3DbGetEntries, CPUMR3DbGetEntryByIndex"), szPath);
     848                    RTLdrClose(hMod);
     849                }
     850                else
     851                    hrc = setErrorVrc(vrc, tr("Failed to construct load '%s': %Rrc"), szPath, vrc);
     852            }
     853            else
     854                hrc = setErrorVrc(vrc, tr("Failed to construct path to the VMM DLL/Dylib/SharedObject: %Rrc"), vrc);
     855        }
     856    }
     857    if (SUCCEEDED(hrc))
     858    {
     859        /*
     860         * Return the matching profiles.
     861         */
     862        /* Count matches: */
     863        size_t cMatches = 0;
     864        for (CPUProfileList_T::const_iterator it = m_llCPUProfiles.begin(); it != m_llCPUProfiles.end(); ++it)
     865            if ((*it)->i_match(aArchitecture, enmSecondaryArch, aNamePattern))
     866                cMatches++;
     867
     868        /* Resize the output array. */
     869        try
     870        {
     871            aProfiles.resize(cMatches);
     872        }
     873        catch (std::bad_alloc &)
     874        {
     875            aProfiles.resize(0);
     876            hrc = E_OUTOFMEMORY;
     877        }
     878
     879        /* Get the return objects: */
     880        if (SUCCEEDED(hrc) && cMatches > 0)
     881        {
     882            size_t iMatch = 0;
     883            for (CPUProfileList_T::const_iterator it = m_llCPUProfiles.begin(); it != m_llCPUProfiles.end(); ++it)
     884                if ((*it)->i_match(aArchitecture, enmSecondaryArch, aNamePattern))
     885                {
     886                    AssertBreakStmt(iMatch < cMatches, hrc = E_UNEXPECTED);
     887                    hrc = (*it).queryInterfaceTo(aProfiles[iMatch].asOutParam());
     888                    if (SUCCEEDED(hrc))
     889                        iMatch++;
     890                    else
     891                        break;
     892                }
     893            AssertStmt(iMatch == cMatches || FAILED(hrc), hrc = E_UNEXPECTED);
     894        }
     895    }
     896    return hrc;
     897}
     898
    712899
    713900HRESULT SystemProperties::getDefaultMachineFolder(com::Utf8Str &aDefaultMachineFolder)
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