Changeset 102828 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Jan 11, 2024 1:47:40 AM (14 months ago)
- svn:sync-xref-src-repo-rev:
- 161022
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/STAM.cpp
r102077 r102828 357 357 { 358 358 pCur->pLookup->pDesc = NULL; 359 if ( pCur->enmType != STAMTYPE_INTERNAL_SUM 360 && pCur->enmType != STAMTYPE_INTERNAL_PCT_OF_SUM) 361 { /* likely*/ } 362 else 363 RTMemFree(pCur->u.pSum); 359 364 RTMemFree(pCur); 360 365 } … … 394 399 STAMUNIT enmUnit, const char *pszDesc) 395 400 { 396 AssertReturn(enmType != STAMTYPE_CALLBACK , VERR_INVALID_PARAMETER);401 AssertReturn(enmType != STAMTYPE_CALLBACK && enmType < STAMTYPE_FIRST_INTERNAL_TYPE, VERR_INVALID_PARAMETER); 397 402 UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE); 398 403 return stamR3RegisterU(pUVM, pvSample, NULL, NULL, enmType, enmVisibility, pszName, enmUnit, pszDesc, STAM_REFRESH_GRP_NONE); … … 425 430 STAMUNIT enmUnit, const char *pszDesc) 426 431 { 427 AssertReturn(enmType != STAMTYPE_CALLBACK , VERR_INVALID_PARAMETER);432 AssertReturn(enmType != STAMTYPE_CALLBACK && enmType < STAMTYPE_FIRST_INTERNAL_TYPE, VERR_INVALID_PARAMETER); 428 433 return stamR3RegisterU(pVM->pUVM, pvSample, NULL, NULL, enmType, enmVisibility, pszName, enmUnit, pszDesc, 429 434 STAM_REFRESH_GRP_NONE); … … 630 635 uint8_t iRefreshGrp, const char *pszDesc, const char *pszName, va_list va) 631 636 { 632 AssertReturn(enmType != STAMTYPE_CALLBACK , VERR_INVALID_PARAMETER);637 AssertReturn(enmType != STAMTYPE_CALLBACK && enmType < STAMTYPE_FIRST_INTERNAL_TYPE, VERR_INVALID_PARAMETER); 633 638 634 639 char szFormattedName[STAM_MAX_NAME_LEN + 8]; … … 638 643 UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE); 639 644 return stamR3RegisterU(pUVM, pvSample, NULL, NULL, enmType, enmVisibility, pszName, enmUnit, pszDesc, iRefreshGrp); 645 } 646 647 648 /** 649 * Refreshes the cached sum (STAMSUMSAMPLE::u) of a sum sample. 650 */ 651 static void stamR3SumRefresh(PSTAMSUMSAMPLE pSum) 652 { 653 switch (pSum->enmType) 654 { 655 case STAMTYPE_COUNTER: 656 { 657 uint64_t uSum = 0; 658 uintptr_t i = pSum->cSummands; 659 while (i-- > 0) 660 { 661 PSTAMDESC const pDesc = pSum->apSummands[i]; 662 switch (pDesc->enmType) 663 { 664 case STAMTYPE_COUNTER: 665 uSum += pDesc->u.pCounter->c; 666 break; 667 668 case STAMTYPE_U64: 669 case STAMTYPE_U64_RESET: 670 case STAMTYPE_X64: 671 case STAMTYPE_X64_RESET: 672 uSum += *pDesc->u.pu64; 673 break; 674 675 case STAMTYPE_U32: 676 case STAMTYPE_U32_RESET: 677 case STAMTYPE_X32: 678 case STAMTYPE_X32_RESET: 679 uSum += *pDesc->u.pu32; 680 break; 681 682 case STAMTYPE_U16: 683 case STAMTYPE_U16_RESET: 684 case STAMTYPE_X16: 685 case STAMTYPE_X16_RESET: 686 uSum += *pDesc->u.pu16; 687 break; 688 689 case STAMTYPE_U8: 690 case STAMTYPE_U8_RESET: 691 case STAMTYPE_X8: 692 case STAMTYPE_X8_RESET: 693 uSum += *pDesc->u.pu8; 694 break; 695 696 default: 697 AssertFailedBreak(); 698 } 699 } 700 pSum->u.Counter.c = uSum; 701 break; 702 } 703 704 case STAMTYPE_PROFILE: 705 { 706 uint64_t cPeriods = 0; 707 uint64_t uTotal = 0; 708 uint64_t uMax = 0; 709 uint64_t uMin = UINT64_MAX; 710 uintptr_t i = pSum->cSummands; 711 while (i-- > 0) 712 { 713 PSTAMDESC const pDesc = pSum->apSummands[i]; 714 AssertContinue( pDesc->enmType == STAMTYPE_PROFILE 715 || pDesc->enmType == STAMTYPE_PROFILE_ADV); 716 PSTAMPROFILE const pProfile = pDesc->u.pProfile; 717 cPeriods += pProfile->cPeriods; 718 uTotal += pProfile->cTicks; 719 uint64_t u = pProfile->cTicksMax; 720 if (u > uMax) 721 uMax = u; 722 u = pProfile->cTicksMin; 723 if (u < uMin) 724 uMin = u; 725 } 726 727 pSum->u.Profile.cTicks = uTotal; 728 pSum->u.Profile.cPeriods = cPeriods; 729 pSum->u.Profile.cTicksMin = uMin; 730 pSum->u.Profile.cTicksMax = uMax; 731 break; 732 } 733 734 default: 735 AssertFailedReturnVoid(); 736 } 737 } 738 739 740 /** 741 * Used by STAMR3RegisterSumV to locate the samples to sum up. 742 */ 743 static int stamR3RegisterSumEnumCallback(PSTAMDESC pDesc, void *pvArg) 744 { 745 PSTAMSUMSAMPLE const pSum = (PSTAMSUMSAMPLE)pvArg; 746 if (pSum->cSummands == 0) 747 { 748 /* 749 * The first time around we check that the type is a supported one 750 * and just set the unit. 751 */ 752 switch (pDesc->enmType) 753 { 754 case STAMTYPE_COUNTER: 755 case STAMTYPE_U64: 756 case STAMTYPE_U64_RESET: 757 case STAMTYPE_X64: 758 case STAMTYPE_X64_RESET: 759 case STAMTYPE_U32: 760 case STAMTYPE_U32_RESET: 761 case STAMTYPE_X32: 762 case STAMTYPE_X32_RESET: 763 case STAMTYPE_U16: 764 case STAMTYPE_U16_RESET: 765 case STAMTYPE_X16: 766 case STAMTYPE_X16_RESET: 767 case STAMTYPE_U8: 768 case STAMTYPE_U8_RESET: 769 case STAMTYPE_X8: 770 case STAMTYPE_X8_RESET: 771 pSum->enmType = STAMTYPE_COUNTER; 772 break; 773 774 case STAMTYPE_PROFILE: 775 case STAMTYPE_PROFILE_ADV: 776 pSum->enmType = STAMTYPE_PROFILE; 777 break; 778 779 default: 780 AssertMsgFailedReturn(("Summing up enmType=%d types have not been implemented yet! Sorry.\n", pDesc->enmType), 781 VERR_WRONG_TYPE); 782 } 783 pSum->enmTypeFirst = pDesc->enmType; 784 pSum->enmUnit = pDesc->enmUnit; 785 } 786 else 787 { 788 /* 789 * Make sure additional sample compatible with the first, 790 * both type and unit. 791 */ 792 if (RT_LIKELY( pDesc->enmType == pSum->enmType 793 || pDesc->enmType == (STAMTYPE)pSum->enmTypeFirst)) 794 { /* likely */ } 795 else 796 { 797 switch (pSum->enmType) 798 { 799 case STAMTYPE_COUNTER: 800 AssertMsgReturn( pDesc->enmType == STAMTYPE_COUNTER 801 || pDesc->enmType == STAMTYPE_U64 802 || pDesc->enmType == STAMTYPE_U64_RESET 803 || pDesc->enmType == STAMTYPE_X64 804 || pDesc->enmType == STAMTYPE_X64_RESET 805 || pDesc->enmType == STAMTYPE_U32 806 || pDesc->enmType == STAMTYPE_U32_RESET 807 || pDesc->enmType == STAMTYPE_X32 808 || pDesc->enmType == STAMTYPE_X32_RESET 809 || pDesc->enmType == STAMTYPE_U16 810 || pDesc->enmType == STAMTYPE_U16_RESET 811 || pDesc->enmType == STAMTYPE_X16 812 || pDesc->enmType == STAMTYPE_X16_RESET 813 || pDesc->enmType == STAMTYPE_U8 814 || pDesc->enmType == STAMTYPE_U8_RESET 815 || pDesc->enmType == STAMTYPE_X8 816 || pDesc->enmType == STAMTYPE_X8_RESET, 817 ("Unsupported type mixup: %d & %d (%s)\n", pSum->enmType, pDesc->enmType, pDesc->pszName), 818 VERR_MISMATCH); 819 break; 820 821 case STAMTYPE_PROFILE: 822 AssertMsgReturn( pDesc->enmType == STAMTYPE_PROFILE 823 || pDesc->enmType == STAMTYPE_PROFILE_ADV, 824 ("Unsupported type mixup: %d & %d (%s)\n", pSum->enmType, pDesc->enmType, pDesc->pszName), 825 VERR_MISMATCH); 826 break; 827 828 default: 829 AssertFailedReturn(VERR_MISMATCH); 830 } 831 } 832 833 if (RT_LIKELY(pDesc->enmUnit == pSum->enmUnit)) 834 { /* likely */ } 835 else if (pDesc->enmUnit != STAMUNIT_NONE) 836 { 837 AssertReturn(pSum->enmUnit == STAMUNIT_NONE, VERR_MISMATCH); 838 pSum->enmUnit = pDesc->enmUnit; 839 } 840 841 AssertReturn(pSum->cSummands < pSum->cSummandsAlloc, VERR_TOO_MUCH_DATA); 842 } 843 pSum->apSummands[pSum->cSummands++] = pDesc; 844 return VINF_SUCCESS; 845 } 846 847 848 /** 849 * Registers a sum that is to be calculated from the @a pszSummandPattern hits. 850 * 851 * @returns VBox status code. 852 * @param pUVM Pointer to the user mode VM structure. 853 * @param enmVisibility Visibility type specifying whether unused statistics should be visible or not. 854 * @param pszSummandPattern A simple pattern for the elements that should be 855 * summed up. These must have matching types and 856 * units. 857 * @param pszDesc Sample description. 858 * @param pszName The sample name format string. 859 * @param va Arguments to the format string. 860 */ 861 VMMR3DECL(int) STAMR3RegisterSumV(PUVM pUVM, STAMVISIBILITY enmVisibility, const char *pszSummandPattern, 862 const char *pszDesc, const char *pszName, va_list va) 863 { 864 char szFormattedName[STAM_MAX_NAME_LEN + 8]; 865 size_t cch = RTStrPrintfV(szFormattedName, sizeof(szFormattedName), pszName, va); 866 AssertReturn(cch <= STAM_MAX_NAME_LEN, VERR_OUT_OF_RANGE); 867 868 UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE); 869 870 /* 871 * We have to resolve the summands before we continue with the actual registration. 872 */ 873 uint8_t const cMaxSummands = 32; 874 PSTAMSUMSAMPLE const pSum = (PSTAMSUMSAMPLE)RTMemAllocZ(RT_UOFFSETOF_DYN(STAMSUMSAMPLE, apSummands[cMaxSummands])); 875 AssertReturn(pSum, VERR_NO_MEMORY); 876 pSum->cSummandsAlloc = cMaxSummands; 877 878 STAM_LOCK_WR(pUVM); 879 880 int rc = stamR3EnumU(pUVM, pszSummandPattern, false /*fUpdateRing0*/, stamR3RegisterSumEnumCallback, pSum); 881 if (RT_SUCCESS(rc)) 882 { 883 if (pSum->cSummands > 0) 884 rc = stamR3RegisterU(pUVM, pSum, NULL, NULL, STAMTYPE_INTERNAL_SUM, enmVisibility, szFormattedName, 885 (STAMUNIT)pSum->enmUnit, pszDesc, STAM_REFRESH_GRP_NONE); 886 else 887 AssertFailedStmt(rc = VERR_NO_DATA); 888 } 889 890 STAM_UNLOCK_WR(pUVM); 891 892 if (RT_FAILURE(rc)) 893 RTMemFree(pSum); 894 return rc; 895 } 896 897 898 /** 899 * Registers a sum that is to be calculated from the @a pszSummandPattern hits. 900 * 901 * @returns VBox status code. 902 * @param pUVM Pointer to the user mode VM structure. 903 * @param enmVisibility Visibility type specifying whether unused statistics should be visible or not. 904 * @param pszSummandPattern A simple pattern for the elements that should be 905 * summed up. These must have matching types and 906 * units. 907 * @param pszDesc Sample description. 908 * @param pszName The sample name format string. 909 * @param ... Arguments to the format string. 910 */ 911 VMMR3DECL(int) STAMR3RegisterSum(PUVM pUVM, STAMVISIBILITY enmVisibility, const char *pszSummandPattern, 912 const char *pszDesc, const char *pszName, ...) 913 { 914 va_list va; 915 va_start(va, pszName); 916 int rc = STAMR3RegisterSumV(pUVM, enmVisibility, pszSummandPattern, pszDesc, pszName, va); 917 va_end(va); 918 return rc; 919 } 920 921 922 /** 923 * Refreshes the cached value (STAMSUMSAMPLE::u) of a percent-of-sum sample. 924 */ 925 static void stamR3PctOfSumRefresh(PSTAMDESC pDesc, PSTAMSUMSAMPLE pSum) 926 { 927 /* 928 * First the value so we only read it once. 929 */ 930 PSTAMDESC const pValDesc = pSum->apSummands[0]; 931 uint64_t uValue; 932 switch (pValDesc->enmType) 933 { 934 case STAMTYPE_COUNTER: 935 uValue = pValDesc->u.pCounter->c; 936 break; 937 938 case STAMTYPE_U64: 939 case STAMTYPE_U64_RESET: 940 case STAMTYPE_X64: 941 case STAMTYPE_X64_RESET: 942 uValue = *pValDesc->u.pu64; 943 break; 944 945 case STAMTYPE_U32: 946 case STAMTYPE_U32_RESET: 947 case STAMTYPE_X32: 948 case STAMTYPE_X32_RESET: 949 uValue = *pValDesc->u.pu32; 950 break; 951 952 case STAMTYPE_U16: 953 case STAMTYPE_U16_RESET: 954 case STAMTYPE_X16: 955 case STAMTYPE_X16_RESET: 956 uValue = *pValDesc->u.pu16; 957 break; 958 959 case STAMTYPE_U8: 960 case STAMTYPE_U8_RESET: 961 case STAMTYPE_X8: 962 case STAMTYPE_X8_RESET: 963 uValue = *pValDesc->u.pu8; 964 break; 965 966 case STAMTYPE_PROFILE: 967 case STAMTYPE_PROFILE_ADV: 968 uValue = pValDesc->u.pProfile->cTicks; 969 break; 970 971 case STAMTYPE_INTERNAL_SUM: 972 { 973 PSTAMSUMSAMPLE const pSubSum = pValDesc->u.pSum; 974 stamR3SumRefresh(pSubSum); 975 if (pSubSum->enmType == STAMTYPE_COUNTER) 976 uValue = pSubSum->u.Counter.c; 977 else 978 uValue = pSubSum->u.Profile.cTicks; 979 break; 980 } 981 982 default: 983 AssertFailedReturnVoid(); 984 } 985 986 /* 987 * Sum it up with the rest. 988 */ 989 uint64_t uSum = uValue; 990 uintptr_t i = pSum->cSummands; 991 while (i-- > 1) 992 { 993 PSTAMDESC const pSummandDesc = pSum->apSummands[i]; 994 switch (pSummandDesc->enmType) 995 { 996 case STAMTYPE_COUNTER: 997 uSum += pSummandDesc->u.pCounter->c; 998 break; 999 1000 case STAMTYPE_U64: 1001 case STAMTYPE_U64_RESET: 1002 case STAMTYPE_X64: 1003 case STAMTYPE_X64_RESET: 1004 uSum += *pSummandDesc->u.pu64; 1005 break; 1006 1007 case STAMTYPE_U32: 1008 case STAMTYPE_U32_RESET: 1009 case STAMTYPE_X32: 1010 case STAMTYPE_X32_RESET: 1011 uSum += *pSummandDesc->u.pu32; 1012 break; 1013 1014 case STAMTYPE_U16: 1015 case STAMTYPE_U16_RESET: 1016 case STAMTYPE_X16: 1017 case STAMTYPE_X16_RESET: 1018 uSum += *pSummandDesc->u.pu16; 1019 break; 1020 1021 case STAMTYPE_U8: 1022 case STAMTYPE_U8_RESET: 1023 case STAMTYPE_X8: 1024 case STAMTYPE_X8_RESET: 1025 uSum += *pSummandDesc->u.pu8; 1026 break; 1027 1028 case STAMTYPE_PROFILE: 1029 case STAMTYPE_PROFILE_ADV: 1030 uSum += pSummandDesc->u.pProfile->cTicks; 1031 break; 1032 1033 case STAMTYPE_INTERNAL_SUM: 1034 { 1035 PSTAMSUMSAMPLE const pSubSum = pSummandDesc->u.pSum; 1036 stamR3SumRefresh(pSubSum); 1037 if (pSubSum->enmType == STAMTYPE_COUNTER) 1038 uSum += pSubSum->u.Counter.c; 1039 else 1040 uSum += pSubSum->u.Profile.cTicks; 1041 break; 1042 } 1043 1044 default: 1045 AssertFailedBreak(); 1046 } 1047 } 1048 1049 /* 1050 * Calculate the percentage. 1051 */ 1052 if (uSum && uValue) 1053 { 1054 switch (pDesc->enmUnit) 1055 { 1056 case STAMUNIT_PCT: 1057 pSum->u.Counter.c = uValue * 100 / uSum; 1058 break; 1059 case STAMUNIT_PP1K: 1060 pSum->u.Counter.c = uValue * 1000 / uSum; 1061 break; 1062 case STAMUNIT_PP10K: 1063 pSum->u.Counter.c = uValue * 10000 / uSum; 1064 break; 1065 default: 1066 AssertFailed(); 1067 RT_FALL_THROUGH(); 1068 case STAMUNIT_PPM: 1069 pSum->u.Counter.c = uValue * 1000000 / uSum; 1070 break; 1071 case STAMUNIT_PPB: 1072 pSum->u.Counter.c = uValue * 1000000000 / uSum; 1073 break; 1074 } 1075 } 1076 else 1077 pSum->u.Counter.c = 0; 1078 } 1079 1080 1081 /** 1082 * Used by STAMR3RegisterPctOfSumV to locate the value to turn into a 1083 * percentage. 1084 */ 1085 static int stamR3RegisterPctOfSumEnumCallbackForValue(PSTAMDESC pDesc, void *pvArg) 1086 { 1087 PSTAMSUMSAMPLE const pSum = (PSTAMSUMSAMPLE)pvArg; 1088 AssertReturn(pSum->cSummands == 0, VERR_TOO_MUCH_DATA); 1089 1090 /* 1091 * Check for compatibility. 1092 */ 1093 switch (pDesc->enmType) 1094 { 1095 case STAMTYPE_COUNTER: 1096 case STAMTYPE_U64: 1097 case STAMTYPE_U64_RESET: 1098 case STAMTYPE_X64: 1099 case STAMTYPE_X64_RESET: 1100 case STAMTYPE_U32: 1101 case STAMTYPE_U32_RESET: 1102 case STAMTYPE_X32: 1103 case STAMTYPE_X32_RESET: 1104 case STAMTYPE_U16: 1105 case STAMTYPE_U16_RESET: 1106 case STAMTYPE_X16: 1107 case STAMTYPE_X16_RESET: 1108 case STAMTYPE_U8: 1109 case STAMTYPE_U8_RESET: 1110 case STAMTYPE_X8: 1111 case STAMTYPE_X8_RESET: 1112 case STAMTYPE_PROFILE: 1113 case STAMTYPE_PROFILE_ADV: 1114 case STAMTYPE_INTERNAL_SUM: 1115 break; 1116 1117 default: 1118 AssertMsgFailedReturn(("Pct-of-sum for enmType=%d types have not been implemented yet! Sorry.\n", pDesc->enmType), 1119 VERR_WRONG_TYPE); 1120 } 1121 pSum->enmTypeFirst = pDesc->enmType; 1122 pSum->apSummands[0] = pDesc; 1123 pSum->cSummands = 1; 1124 return VINF_SUCCESS; 1125 } 1126 1127 1128 /** 1129 * Used by STAMR3RegisterPctOfSumV to locate the samples to sum up. 1130 */ 1131 static int stamR3RegisterPctOfSumEnumCallbackForSummands(PSTAMDESC pDesc, void *pvArg) 1132 { 1133 PSTAMSUMSAMPLE const pSum = (PSTAMSUMSAMPLE)pvArg; 1134 1135 /* 1136 * Skip if the same as the value we're calculating the percentage for. 1137 */ 1138 if (pDesc == pSum->apSummands[0]) 1139 return VINF_SUCCESS; 1140 1141 /* 1142 * Make sure additional samples are compatible with the first as far as type. 1143 */ 1144 if (RT_LIKELY( pDesc->enmType == pSum->enmType 1145 || pDesc->enmType == (STAMTYPE)pSum->enmTypeFirst)) 1146 { /* likely */ } 1147 else 1148 { 1149 switch (pDesc->enmType) 1150 { 1151 case STAMTYPE_COUNTER: 1152 case STAMTYPE_U64: 1153 case STAMTYPE_U64_RESET: 1154 case STAMTYPE_X64: 1155 case STAMTYPE_X64_RESET: 1156 case STAMTYPE_U32: 1157 case STAMTYPE_U32_RESET: 1158 case STAMTYPE_X32: 1159 case STAMTYPE_X32_RESET: 1160 case STAMTYPE_U16: 1161 case STAMTYPE_U16_RESET: 1162 case STAMTYPE_X16: 1163 case STAMTYPE_X16_RESET: 1164 case STAMTYPE_U8: 1165 case STAMTYPE_U8_RESET: 1166 case STAMTYPE_X8: 1167 case STAMTYPE_X8_RESET: 1168 case STAMTYPE_PROFILE: 1169 case STAMTYPE_PROFILE_ADV: 1170 case STAMTYPE_INTERNAL_SUM: 1171 break; 1172 1173 default: 1174 AssertMsgFailedReturn(("Unsupported pct-of-sum type: %d (%s)\n", pDesc->enmType, pDesc->pszName), VERR_MISMATCH); 1175 } 1176 } 1177 1178 AssertReturn(pSum->cSummands < pSum->cSummandsAlloc, VERR_TOO_MUCH_DATA); 1179 pSum->apSummands[pSum->cSummands++] = pDesc; 1180 return VINF_SUCCESS; 1181 } 1182 1183 1184 /** 1185 * Registers a percentage of a sum that is to be calculated from @a pszValue and 1186 * the @a pszSummandPattern hits. 1187 * 1188 * @returns VBox status code. 1189 * @param pUVM Pointer to the user mode VM structure. 1190 * @param enmVisibility Visibility type specifying whether unused statistics should be visible or not. 1191 * @param enmUnit The sample unit: STAMUNIT_PCT, STAMUNIT_PP1K, 1192 * STAMUNIT_PP10K, STAMUNIT_PPM or STAMUNIT_PPB. 1193 * @param pszName Name of the sample which value should be put 1194 * against the sum of all. 1195 * @param pszSummandPattern A simple pattern for the elements that should be 1196 * summed up and used to divide @a pszName by when 1197 * calculating the percentage. These must have 1198 * compatible types. 1199 * 1200 * The @a pszName is implicitly included in the sum. 1201 * 1202 * @param pszDesc Sample description. 1203 * @param pszName The sample name format string. 1204 * @param va Arguments to the format string. 1205 */ 1206 VMMR3DECL(int) STAMR3RegisterPctOfSumV(PUVM pUVM, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, const char *pszValue, 1207 const char *pszSummandPattern, const char *pszDesc, const char *pszName, va_list va) 1208 { 1209 char szFormattedName[STAM_MAX_NAME_LEN + 8]; 1210 size_t cch = RTStrPrintfV(szFormattedName, sizeof(szFormattedName), pszName, va); 1211 AssertReturn(cch <= STAM_MAX_NAME_LEN, VERR_OUT_OF_RANGE); 1212 switch (enmUnit) 1213 { 1214 case STAMUNIT_PCT: 1215 case STAMUNIT_PP1K: 1216 case STAMUNIT_PP10K: 1217 case STAMUNIT_PPM: 1218 case STAMUNIT_PPB: 1219 break; 1220 default: 1221 AssertFailedReturn(VERR_INVALID_PARAMETER); 1222 } 1223 1224 UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE); 1225 1226 /* 1227 * We have to resolve the value and summands before we continue with the 1228 * actual registration. We reuse the STAMSUMSAMPLE structure here. 1229 */ 1230 uint8_t const cMaxSummands = 32; 1231 PSTAMSUMSAMPLE const pSum = (PSTAMSUMSAMPLE)RTMemAllocZ(RT_UOFFSETOF_DYN(STAMSUMSAMPLE, apSummands[cMaxSummands])); 1232 AssertReturn(pSum, VERR_NO_MEMORY); 1233 pSum->cSummandsAlloc = cMaxSummands; 1234 pSum->enmType = STAMTYPE_COUNTER; 1235 pSum->enmUnit = enmUnit; 1236 1237 STAM_LOCK_WR(pUVM); 1238 1239 /* The first summand entry is the value. */ 1240 int rc = stamR3EnumU(pUVM, pszValue, false /*fUpdateRing0*/, stamR3RegisterPctOfSumEnumCallbackForValue, pSum); 1241 if (RT_SUCCESS(rc)) 1242 { 1243 if (pSum->cSummands == 1) 1244 { 1245 /* The additional ones are part of the sum we should divide the value by. */ 1246 rc = stamR3EnumU(pUVM, pszSummandPattern, false /*fUpdateRing0*/, stamR3RegisterPctOfSumEnumCallbackForSummands, pSum); 1247 if (RT_SUCCESS(rc)) 1248 { 1249 /* Now, register it. */ 1250 if (pSum->cSummands > 1) 1251 rc = stamR3RegisterU(pUVM, pSum, NULL, NULL, STAMTYPE_INTERNAL_PCT_OF_SUM, enmVisibility, szFormattedName, 1252 (STAMUNIT)pSum->enmUnit, pszDesc, STAM_REFRESH_GRP_NONE); 1253 else 1254 AssertFailedStmt(rc = VERR_NO_DATA); 1255 } 1256 } 1257 else 1258 AssertFailedStmt(rc = VERR_NO_DATA); 1259 } 1260 1261 STAM_UNLOCK_WR(pUVM); 1262 1263 if (RT_FAILURE(rc)) 1264 RTMemFree(pSum); 1265 return rc; 1266 } 1267 1268 1269 /** 1270 * Registers a percentage of a sum that is to be calculated from @a pszValue and 1271 * the @a pszSummandPattern hits. 1272 * 1273 * @returns VBox status code. 1274 * @param pUVM Pointer to the user mode VM structure. 1275 * @param enmVisibility Visibility type specifying whether unused statistics should be visible or not. 1276 * @param enmUnit The sample unit: STAMUNIT_PCT, STAMUNIT_PP1K, 1277 * STAMUNIT_PP10K, STAMUNIT_PPM or STAMUNIT_PPB. 1278 * @param pszName Name of the sample which value should be put 1279 * against the sum of all. 1280 * @param pszSummandPattern A simple pattern for the elements that should be 1281 * summed up and used to divide @a pszName by when 1282 * calculating the percentage. These must have 1283 * compatible types. 1284 * 1285 * The @a pszName is implicitly included in the sum. 1286 * 1287 * @param pszDesc Sample description. 1288 * @param pszName The sample name format string. 1289 * @param ... Arguments to the format string. 1290 */ 1291 VMMR3DECL(int) STAMR3RegisterPctOfSum(PUVM pUVM, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, const char *pszValue, 1292 const char *pszSummandPattern, const char *pszDesc, const char *pszName, ...) 1293 { 1294 va_list va; 1295 va_start(va, pszName); 1296 int rc = STAMR3RegisterPctOfSumV(pUVM, enmVisibility, enmUnit, pszValue, pszSummandPattern, pszDesc, pszName, va); 1297 va_end(va); 1298 return rc; 640 1299 } 641 1300 … … 1549 2208 switch (enmType) 1550 2209 { 1551 2210 /* 8 byte / 64-bit */ 1552 2211 case STAMTYPE_U64: 1553 2212 case STAMTYPE_U64_RESET: … … 1560 2219 break; 1561 2220 1562 2221 /* 4 byte / 32-bit */ 1563 2222 case STAMTYPE_RATIO_U32: 1564 2223 case STAMTYPE_RATIO_U32_RESET: … … 1570 2229 break; 1571 2230 1572 2231 /* 2 byte / 32-bit */ 1573 2232 case STAMTYPE_U16: 1574 2233 case STAMTYPE_U16_RESET: … … 1578 2237 break; 1579 2238 1580 2239 /* 1 byte / 8-bit / unaligned */ 1581 2240 case STAMTYPE_U8: 1582 2241 case STAMTYPE_U8_RESET: … … 1586 2245 case STAMTYPE_BOOL_RESET: 1587 2246 case STAMTYPE_CALLBACK: 2247 case STAMTYPE_INTERNAL_SUM: 2248 case STAMTYPE_INTERNAL_PCT_OF_SUM: 1588 2249 break; 1589 2250 … … 1651 2312 stamR3LookupDecUsage(pCur->pLookup); 1652 2313 stamR3LookupMaybeFree(pCur->pLookup); 2314 if ( pCur->enmType != STAMTYPE_INTERNAL_SUM 2315 && pCur->enmType != STAMTYPE_INTERNAL_PCT_OF_SUM) 2316 { /* likely */ } 2317 else 2318 RTMemFree(pCur->u.pSum); 1653 2319 RTMemFree(pCur); 1654 2320 … … 2006 2672 case STAMTYPE_RATIO_U32: 2007 2673 case STAMTYPE_BOOL: 2674 case STAMTYPE_INTERNAL_SUM: 2675 case STAMTYPE_INTERNAL_PCT_OF_SUM: 2008 2676 break; 2009 2677 … … 2178 2846 break; 2179 2847 2848 case STAMTYPE_INTERNAL_SUM: 2849 { 2850 PSTAMSUMSAMPLE const pSum = pDesc->u.pSum; 2851 stamR3SumRefresh(pSum); 2852 switch (pSum->enmType) 2853 { 2854 case STAMTYPE_COUNTER: 2855 if (pDesc->enmVisibility == STAMVISIBILITY_USED && pSum->u.Counter.c == 0) 2856 return VINF_SUCCESS; 2857 stamR3SnapshotPrintf(pThis, "<Counter c=\"%lld\"", pSum->u.Counter.c); 2858 break; 2859 2860 case STAMTYPE_PROFILE: 2861 if (pDesc->enmVisibility == STAMVISIBILITY_USED && pSum->u.Profile.cPeriods == 0) 2862 return VINF_SUCCESS; 2863 stamR3SnapshotPrintf(pThis, "<Profile cPeriods=\"%lld\" cTicks=\"%lld\" cTicksMin=\"%lld\" cTicksMax=\"%lld\"", 2864 pSum->u.Profile.cPeriods, pSum->u.Profile.cTicks, pSum->u.Profile.cTicksMin, 2865 pSum->u.Profile.cTicksMax); 2866 break; 2867 2868 default: 2869 AssertMsgFailedReturn(("%d\n", pSum->enmType), VINF_SUCCESS); 2870 } 2871 break; 2872 } 2873 2874 case STAMTYPE_INTERNAL_PCT_OF_SUM: 2875 { 2876 PSTAMSUMSAMPLE const pSum = pDesc->u.pSum; 2877 stamR3PctOfSumRefresh(pDesc, pSum); 2878 if (pDesc->enmVisibility == STAMVISIBILITY_USED && pSum->u.Counter.c == 0) 2879 return VINF_SUCCESS; 2880 stamR3SnapshotPrintf(pThis, "<Counter c=\"%lld\"", pSum->u.Counter.c); 2881 break; 2882 } 2883 2180 2884 default: 2181 AssertMsgFailed(("%d\n", pDesc->enmType)); 2182 return 0; 2885 AssertMsgFailedReturn(("%d\n", pDesc->enmType), VINF_SUCCESS); 2183 2886 } 2184 2887 … … 2472 3175 return VINF_SUCCESS; 2473 3176 2474 uint64_t u64 = pDesc->u.pProfile->cPeriods ? pDesc->u.pProfile->cPeriods : 1;3177 uint64_t const u64 = pDesc->u.pProfile->cPeriods ? pDesc->u.pProfile->cPeriods : 1; 2475 3178 pArgs->pfnPrintf(pArgs, "%-32s %8llu %s (%12llu %s, %7llu %s, max %9llu, min %7lld)\n", pDesc->pszName, 2476 3179 pDesc->u.pProfile->cTicks / u64, STAMR3GetUnit(pDesc->enmUnit), … … 2560 3263 break; 2561 3264 3265 case STAMTYPE_INTERNAL_SUM: 3266 { 3267 PSTAMSUMSAMPLE const pSum = pDesc->u.pSum; 3268 stamR3SumRefresh(pSum); 3269 switch (pSum->enmType) 3270 { 3271 case STAMTYPE_COUNTER: 3272 if (pDesc->enmVisibility == STAMVISIBILITY_USED && pSum->u.Counter.c == 0) 3273 return VINF_SUCCESS; 3274 pArgs->pfnPrintf(pArgs, "%-32s %8llu %s\n", pDesc->pszName, pSum->u.Counter.c, STAMR3GetUnit(pDesc->enmUnit)); 3275 break; 3276 3277 case STAMTYPE_PROFILE: 3278 { 3279 if (pDesc->enmVisibility == STAMVISIBILITY_USED && pSum->u.Profile.cPeriods == 0) 3280 return VINF_SUCCESS; 3281 3282 uint64_t const u64 = pSum->u.Profile.cPeriods ? pSum->u.Profile.cPeriods : 1; 3283 pArgs->pfnPrintf(pArgs, "%-32s %8llu %s (%12llu %s, %7llu %s, max %9llu, min %7lld)\n", pDesc->pszName, 3284 pSum->u.Profile.cTicks / u64, STAMR3GetUnit(pDesc->enmUnit), 3285 pSum->u.Profile.cTicks, STAMR3GetUnit1(pDesc->enmUnit), 3286 pSum->u.Profile.cPeriods, STAMR3GetUnit2(pDesc->enmUnit), 3287 pSum->u.Profile.cTicksMax, pSum->u.Profile.cTicksMin); 3288 break; 3289 } 3290 3291 default: 3292 AssertMsgFailed(("%d\n", pSum->enmType)); 3293 break; 3294 } 3295 break; 3296 } 3297 3298 case STAMTYPE_INTERNAL_PCT_OF_SUM: 3299 { 3300 PSTAMSUMSAMPLE const pSum = pDesc->u.pSum; 3301 stamR3PctOfSumRefresh(pDesc, pSum); 3302 if (pDesc->enmVisibility == STAMVISIBILITY_USED && pSum->u.Counter.c == 0) 3303 return VINF_SUCCESS; 3304 pArgs->pfnPrintf(pArgs, "%-32s %8llu %s\n", pDesc->pszName, pSum->u.Counter.c, STAMR3GetUnit(pDesc->enmUnit)); 3305 break; 3306 } 3307 2562 3308 default: 2563 3309 AssertMsgFailed(("enmType=%d\n", pDesc->enmType)); 2564 3310 break; 2565 3311 } 2566 NOREF(pvArg);2567 3312 return VINF_SUCCESS; 2568 3313 } … … 2602 3347 static int stamR3EnumOne(PSTAMDESC pDesc, void *pvArg) 2603 3348 { 2604 PSTAMR3ENUMONEARGS pArgs = (PSTAMR3ENUMONEARGS)pvArg; 2605 const char *pszUnit = STAMR3GetUnit(pDesc->enmUnit); 2606 int rc; 2607 if (pDesc->enmType == STAMTYPE_CALLBACK) 2608 { 2609 /* Give the enumerator something useful. */ 2610 char szBuf[512]; 2611 pDesc->u.Callback.pfnPrint(pArgs->pVM, pDesc->u.Callback.pvSample, szBuf, sizeof(szBuf)); 2612 rc = pArgs->pfnEnum(pDesc->pszName, pDesc->enmType, szBuf, pDesc->enmUnit, pszUnit, 2613 pDesc->enmVisibility, pDesc->pszDesc, pArgs->pvUser); 2614 } 2615 else 2616 rc = pArgs->pfnEnum(pDesc->pszName, pDesc->enmType, pDesc->u.pv, pDesc->enmUnit, pszUnit, 2617 pDesc->enmVisibility, pDesc->pszDesc, pArgs->pvUser); 2618 return rc; 3349 PSTAMR3ENUMONEARGS const pArgs = (PSTAMR3ENUMONEARGS)pvArg; 3350 const char * const pszUnit = STAMR3GetUnit(pDesc->enmUnit); 3351 switch (pDesc->enmType) 3352 { 3353 default: 3354 return pArgs->pfnEnum(pDesc->pszName, pDesc->enmType, pDesc->u.pv, pDesc->enmUnit, pszUnit, 3355 pDesc->enmVisibility, pDesc->pszDesc, pArgs->pvUser); 3356 3357 case STAMTYPE_CALLBACK: 3358 { 3359 /* Give the enumerator something useful. */ 3360 char szBuf[512]; 3361 pDesc->u.Callback.pfnPrint(pArgs->pVM, pDesc->u.Callback.pvSample, szBuf, sizeof(szBuf)); 3362 return pArgs->pfnEnum(pDesc->pszName, pDesc->enmType, szBuf, pDesc->enmUnit, pszUnit, 3363 pDesc->enmVisibility, pDesc->pszDesc, pArgs->pvUser); 3364 } 3365 3366 case STAMTYPE_INTERNAL_SUM: 3367 { 3368 PSTAMSUMSAMPLE const pSum = pDesc->u.pSum; 3369 stamR3SumRefresh(pSum); 3370 return pArgs->pfnEnum(pDesc->pszName, pSum->enmType, &pSum->u, pDesc->enmUnit, pszUnit, 3371 pDesc->enmVisibility, pDesc->pszDesc, pArgs->pvUser); 3372 } 3373 3374 case STAMTYPE_INTERNAL_PCT_OF_SUM: 3375 { 3376 PSTAMSUMSAMPLE const pSum = pDesc->u.pSum; 3377 stamR3PctOfSumRefresh(pDesc, pSum); 3378 return pArgs->pfnEnum(pDesc->pszName, pSum->enmType, &pSum->u, pDesc->enmUnit, pszUnit, 3379 pDesc->enmVisibility, pDesc->pszDesc, pArgs->pvUser); 3380 } 3381 } 2619 3382 } 2620 3383 … … 3059 3822 case STAMUNIT_NS_PER_OCCURENCE: return "ns/time"; 3060 3823 case STAMUNIT_PCT: return "%"; 3824 case STAMUNIT_PP1K: return "pp1k"; 3825 case STAMUNIT_PP10K: return "pp10k"; 3826 case STAMUNIT_PPM: return "ppm"; 3827 case STAMUNIT_PPB: return "ppb"; 3061 3828 case STAMUNIT_HZ: return "Hz"; 3062 3829 case STAMUNIT_INSTR: return "instr"; … … 3100 3867 case STAMUNIT_NS_PER_OCCURENCE: return "ns"; 3101 3868 case STAMUNIT_PCT: return "%"; 3869 case STAMUNIT_PP1K: return "pp1k"; 3870 case STAMUNIT_PP10K: return "pp10k"; 3871 case STAMUNIT_PPM: return "ppm"; 3872 case STAMUNIT_PPB: return "ppb"; 3102 3873 case STAMUNIT_HZ: return "Hz"; 3103 3874 case STAMUNIT_INSTR: return "instr";
Note:
See TracChangeset
for help on using the changeset viewer.