VirtualBox

Changeset 102828 in vbox for trunk/src/VBox/VMM/VMMR3


Ignore:
Timestamp:
Jan 11, 2024 1:47:40 AM (14 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
161022
Message:

VMM/STAM: Added two new aggregate sample types. bugref:10371

File:
1 edited

Legend:

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

    r102077 r102828  
    357357    {
    358358        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);
    359364        RTMemFree(pCur);
    360365    }
     
    394399                                STAMUNIT enmUnit, const char *pszDesc)
    395400{
    396     AssertReturn(enmType != STAMTYPE_CALLBACK, VERR_INVALID_PARAMETER);
     401    AssertReturn(enmType != STAMTYPE_CALLBACK && enmType < STAMTYPE_FIRST_INTERNAL_TYPE, VERR_INVALID_PARAMETER);
    397402    UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
    398403    return stamR3RegisterU(pUVM, pvSample, NULL, NULL, enmType, enmVisibility, pszName, enmUnit, pszDesc, STAM_REFRESH_GRP_NONE);
     
    425430                               STAMUNIT enmUnit, const char *pszDesc)
    426431{
    427     AssertReturn(enmType != STAMTYPE_CALLBACK, VERR_INVALID_PARAMETER);
     432    AssertReturn(enmType != STAMTYPE_CALLBACK && enmType < STAMTYPE_FIRST_INTERNAL_TYPE, VERR_INVALID_PARAMETER);
    428433    return stamR3RegisterU(pVM->pUVM, pvSample, NULL, NULL, enmType, enmVisibility, pszName, enmUnit, pszDesc,
    429434                           STAM_REFRESH_GRP_NONE);
     
    630635                                      uint8_t iRefreshGrp, const char *pszDesc, const char *pszName, va_list va)
    631636{
    632     AssertReturn(enmType != STAMTYPE_CALLBACK, VERR_INVALID_PARAMETER);
     637    AssertReturn(enmType != STAMTYPE_CALLBACK && enmType < STAMTYPE_FIRST_INTERNAL_TYPE, VERR_INVALID_PARAMETER);
    633638
    634639    char   szFormattedName[STAM_MAX_NAME_LEN + 8];
     
    638643    UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
    639644    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 */
     651static 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 */
     743static 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 */
     861VMMR3DECL(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 */
     911VMMR3DECL(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 */
     925static 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 */
     1085static 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 */
     1131static 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 */
     1206VMMR3DECL(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 */
     1291VMMR3DECL(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;
    6401299}
    6411300
     
    15492208    switch (enmType)
    15502209    {
    1551             /* 8 byte / 64-bit */
     2210        /* 8 byte / 64-bit */
    15522211        case STAMTYPE_U64:
    15532212        case STAMTYPE_U64_RESET:
     
    15602219            break;
    15612220
    1562             /* 4 byte / 32-bit */
     2221        /* 4 byte / 32-bit */
    15632222        case STAMTYPE_RATIO_U32:
    15642223        case STAMTYPE_RATIO_U32_RESET:
     
    15702229            break;
    15712230
    1572             /* 2 byte / 32-bit */
     2231        /* 2 byte / 32-bit */
    15732232        case STAMTYPE_U16:
    15742233        case STAMTYPE_U16_RESET:
     
    15782237            break;
    15792238
    1580             /* 1 byte / 8-bit / unaligned */
     2239        /* 1 byte / 8-bit / unaligned */
    15812240        case STAMTYPE_U8:
    15822241        case STAMTYPE_U8_RESET:
     
    15862245        case STAMTYPE_BOOL_RESET:
    15872246        case STAMTYPE_CALLBACK:
     2247        case STAMTYPE_INTERNAL_SUM:
     2248        case STAMTYPE_INTERNAL_PCT_OF_SUM:
    15882249            break;
    15892250
     
    16512312    stamR3LookupDecUsage(pCur->pLookup);
    16522313    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);
    16532319    RTMemFree(pCur);
    16542320
     
    20062672        case STAMTYPE_RATIO_U32:
    20072673        case STAMTYPE_BOOL:
     2674        case STAMTYPE_INTERNAL_SUM:
     2675        case STAMTYPE_INTERNAL_PCT_OF_SUM:
    20082676            break;
    20092677
     
    21782846            break;
    21792847
     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
    21802884        default:
    2181             AssertMsgFailed(("%d\n", pDesc->enmType));
    2182             return 0;
     2885            AssertMsgFailedReturn(("%d\n", pDesc->enmType), VINF_SUCCESS);
    21832886    }
    21842887
     
    24723175                return VINF_SUCCESS;
    24733176
    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;
    24753178            pArgs->pfnPrintf(pArgs, "%-32s %8llu %s (%12llu %s, %7llu %s, max %9llu, min %7lld)\n", pDesc->pszName,
    24763179                             pDesc->u.pProfile->cTicks / u64, STAMR3GetUnit(pDesc->enmUnit),
     
    25603263            break;
    25613264
     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
    25623308        default:
    25633309            AssertMsgFailed(("enmType=%d\n", pDesc->enmType));
    25643310            break;
    25653311    }
    2566     NOREF(pvArg);
    25673312    return VINF_SUCCESS;
    25683313}
     
    26023347static int stamR3EnumOne(PSTAMDESC pDesc, void *pvArg)
    26033348{
    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    }
    26193382}
    26203383
     
    30593822        case STAMUNIT_NS_PER_OCCURENCE:     return "ns/time";
    30603823        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";
    30613828        case STAMUNIT_HZ:                   return "Hz";
    30623829        case STAMUNIT_INSTR:                return "instr";
     
    31003867        case STAMUNIT_NS_PER_OCCURENCE:     return "ns";
    31013868        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";
    31023873        case STAMUNIT_HZ:                   return "Hz";
    31033874        case STAMUNIT_INSTR:                return "instr";
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