Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 27bb3ba8 authored by Richard Gaywood's avatar Richard Gaywood Committed by Automerger Merge Worker
Browse files

Merge "Implement procsstats data agggregation" into rvc-dev am: 89e6a4a4 am: ffea2256

Change-Id: I808156c9fa8599f2de1777a16fa8985742afe643
parents bbd67262 ffea2256
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -539,4 +539,11 @@ public final class DumpUtils {
        // Pack screen & process state using bit shifting
        return (procStateIndex << 8) | screenStateIndex;
    }

    /** Print aggregated tags generated via {@code #aggregateCurrentProcessState}. */
    public static void printAggregatedProcStateTagProto(ProtoOutputStream proto, long screenId,
            long stateId, int state) {
        proto.write(screenId, ADJ_SCREEN_PROTO_ENUMS[state >> 8]);
        proto.write(stateId, STATE_PROTO_ENUMS[state]);
    }
}
+119 −16
Original line number Diff line number Diff line
@@ -16,22 +16,6 @@

package com.android.internal.app.procstats;

import android.os.Parcel;
import android.os.SystemClock;
import android.os.UserHandle;
import android.service.procstats.ProcessStatsProto;
import android.service.procstats.ProcessStatsStateProto;
import android.util.ArrayMap;
import android.util.DebugUtils;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.Slog;
import android.util.SparseLongArray;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
import android.util.proto.ProtoUtils;


import static com.android.internal.app.procstats.ProcessStats.PSS_AVERAGE;
import static com.android.internal.app.procstats.ProcessStats.PSS_COUNT;
import static com.android.internal.app.procstats.ProcessStats.PSS_MAXIMUM;
@@ -60,6 +44,21 @@ import static com.android.internal.app.procstats.ProcessStats.STATE_SERVICE;
import static com.android.internal.app.procstats.ProcessStats.STATE_SERVICE_RESTARTING;
import static com.android.internal.app.procstats.ProcessStats.STATE_TOP;

import android.os.Parcel;
import android.os.SystemClock;
import android.os.UserHandle;
import android.service.procstats.ProcessStatsProto;
import android.service.procstats.ProcessStatsStateProto;
import android.util.ArrayMap;
import android.util.DebugUtils;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.Slog;
import android.util.SparseLongArray;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
import android.util.proto.ProtoUtils;

import com.android.internal.app.procstats.ProcessStats.PackageState;
import com.android.internal.app.procstats.ProcessStats.ProcessStateHolder;
import com.android.internal.app.procstats.ProcessStats.TotalMemoryUseCollection;
@@ -1418,4 +1417,108 @@ public final class ProcessState {

        proto.end(token);
    }

    /** Similar to {@code #dumpDebug}, but with a reduced/aggregated subset of states. */
    public void dumpAggregatedProtoForStatsd(ProtoOutputStream proto, long fieldId,
            String procName, int uid, long now) {
        // Group proc stats by aggregated type (only screen state + process state)
        SparseLongArray durationByState = new SparseLongArray();
        boolean didCurState = false;
        for (int i = 0; i < mDurations.getKeyCount(); i++) {
            final int key = mDurations.getKeyAt(i);
            final int type = SparseMappingTable.getIdFromKey(key);
            final int aggregatedType = DumpUtils.aggregateCurrentProcessState(type);

            long time = mDurations.getValue(key);
            if (mCurCombinedState == type) {
                didCurState = true;
                time += now - mStartTime;
            }
            int index = durationByState.indexOfKey(aggregatedType);
            if (index >= 0) {
                durationByState.put(aggregatedType, time + durationByState.valueAt(aggregatedType));
            } else {
                durationByState.put(aggregatedType, time);
            }
        }
        if (!didCurState && mCurCombinedState != STATE_NOTHING) {
            final int aggregatedType = DumpUtils.aggregateCurrentProcessState(mCurCombinedState);
            int index = durationByState.indexOfKey(aggregatedType);
            if (index >= 0) {
                durationByState.put(aggregatedType,
                        (now - mStartTime) + durationByState.valueAt(index));
            } else {
                durationByState.put(aggregatedType, now - mStartTime);
            }
        }

        // Now we have total durations, aggregate the RSS values
        SparseLongArray meanRssByState = new SparseLongArray();
        SparseLongArray maxRssByState = new SparseLongArray();
        // compute weighted averages and max-of-max
        for (int i = 0; i < mPssTable.getKeyCount(); i++) {
            final int key = mPssTable.getKeyAt(i);
            final int type = SparseMappingTable.getIdFromKey(key);
            if (durationByState.indexOfKey(type) < 0) {
                // state without duration should not have stats!
                continue;
            }
            final int aggregatedType = DumpUtils.aggregateCurrentProcessState(type);

            long[] rssMeanAndMax = mPssTable.getRssMeanAndMax(key);

            // compute mean * duration, then store sum of that in meanRssByState
            long meanTimesDuration = rssMeanAndMax[0] * mDurations.getValue(key);
            if (meanRssByState.indexOfKey(aggregatedType) >= 0) {
                meanRssByState.put(aggregatedType,
                        meanTimesDuration + meanRssByState.get(aggregatedType));
            } else {
                meanRssByState.put(aggregatedType, meanTimesDuration);
            }

            // accumulate max-of-maxes in maxRssByState
            if (maxRssByState.indexOfKey(aggregatedType) >= 0
                    && maxRssByState.get(aggregatedType) < rssMeanAndMax[1]) {
                maxRssByState.put(aggregatedType, rssMeanAndMax[1]);
            } else if (maxRssByState.indexOfKey(aggregatedType) < 0) {
                maxRssByState.put(aggregatedType, rssMeanAndMax[1]);
            }
        }

        // divide the means by the durations to get the weighted mean-of-means
        for (int i = 0; i < durationByState.size(); i++) {
            int aggregatedKey = durationByState.keyAt(i);
            if (meanRssByState.indexOfKey(aggregatedKey) < 0) {
                // these data structures should be consistent
                continue;
            }
            meanRssByState.put(aggregatedKey,
                    meanRssByState.get(aggregatedKey) / durationByState.get(aggregatedKey));
        }

        // build the output
        final long token = proto.start(fieldId);
        proto.write(ProcessStatsProto.PROCESS, procName);
        proto.write(ProcessStatsProto.UID, uid);

        for (int i = 0; i < durationByState.size(); i++) {
            final int aggregatedKey = mPssTable.getKeyAt(i);

            final long stateToken = proto.start(ProcessStatsProto.STATES);
            DumpUtils.printAggregatedProcStateTagProto(proto,
                    ProcessStatsStateProto.SCREEN_STATE,
                    ProcessStatsStateProto.PROCESS_STATE,
                    durationByState.keyAt(i));
            proto.write(ProcessStatsStateProto.DURATION_MS, durationByState.valueAt(i));

            ProtoUtils.toAggStatsProto(proto, ProcessStatsStateProto.RSS,
                    0, /* do not output a minimum value */
                    meanRssByState.get(aggregatedKey),
                    maxRssByState.get(aggregatedKey));

            proto.end(stateToken);
        }

        proto.end(token);
    }
}
+11 −6
Original line number Diff line number Diff line
@@ -16,17 +16,17 @@

package com.android.internal.app.procstats;

import static com.android.internal.app.procstats.ProcessStats.PSS_AVERAGE;
import static com.android.internal.app.procstats.ProcessStats.PSS_COUNT;
import static com.android.internal.app.procstats.ProcessStats.PSS_MAXIMUM;
import static com.android.internal.app.procstats.ProcessStats.PSS_MINIMUM;
import static com.android.internal.app.procstats.ProcessStats.PSS_RSS_AVERAGE;
import static com.android.internal.app.procstats.ProcessStats.PSS_RSS_MAXIMUM;
import static com.android.internal.app.procstats.ProcessStats.PSS_RSS_MINIMUM;
import static com.android.internal.app.procstats.ProcessStats.PSS_SAMPLE_COUNT;
import static com.android.internal.app.procstats.ProcessStats.PSS_MINIMUM;
import static com.android.internal.app.procstats.ProcessStats.PSS_AVERAGE;
import static com.android.internal.app.procstats.ProcessStats.PSS_MAXIMUM;
import static com.android.internal.app.procstats.ProcessStats.PSS_USS_MINIMUM;
import static com.android.internal.app.procstats.ProcessStats.PSS_USS_AVERAGE;
import static com.android.internal.app.procstats.ProcessStats.PSS_USS_MAXIMUM;
import static com.android.internal.app.procstats.ProcessStats.PSS_COUNT;
import static com.android.internal.app.procstats.ProcessStats.PSS_USS_MINIMUM;

import android.service.procstats.ProcessStatsStateProto;
import android.util.proto.ProtoOutputStream;
@@ -133,7 +133,6 @@ public class PssTable extends SparseMappingTable.Table {
            }

            if (stats[statsIndex + PSS_RSS_MINIMUM] > minRss) {
                stats[statsIndex + PSS_RSS_MINIMUM] = minRss;
            }

            stats[statsIndex + PSS_RSS_AVERAGE] = (long)(((stats[statsIndex + PSS_RSS_AVERAGE]
@@ -167,4 +166,10 @@ public class PssTable extends SparseMappingTable.Table {
                stats[statsIndex + PSS_RSS_AVERAGE],
                stats[statsIndex + PSS_RSS_MAXIMUM]);
    }

    long[] getRssMeanAndMax(int key) {
        final long[] stats = getArrayForKey(key);
        final int statsIndex = SparseMappingTable.getIndexFromKey(key);
        return new long[]{stats[statsIndex + PSS_RSS_AVERAGE], stats[statsIndex + PSS_RSS_MAXIMUM]};
    }
}