Changeset 85574 in vbox for trunk/src/VBox/Main/src-server
- Timestamp:
- Jul 31, 2020 12:45:16 PM (4 years ago)
- 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 23 23 # include "ExtPackManagerImpl.h" 24 24 #endif 25 #include "CPUProfileImpl.h" 25 26 #include "AutoCaller.h" 26 27 #include "Global.h" … … 42 43 #include <VBox/settings.h> 43 44 #include <VBox/vd.h> 45 #include <VBox/vmm/cpum.h> 44 46 45 47 // defines … … 50 52 51 53 SystemProperties::SystemProperties() 52 : mParent(NULL), 53 m(new settings::SystemProperties) 54 : mParent(NULL) 55 , m(new settings::SystemProperties) 56 , m_fLoadedX86CPUProfiles(false) 54 57 { 55 58 } … … 710 713 return S_OK; 711 714 } 715 716 HRESULT 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 712 899 713 900 HRESULT SystemProperties::getDefaultMachineFolder(com::Utf8Str &aDefaultMachineFolder)
Note:
See TracChangeset
for help on using the changeset viewer.