Merge "Implement procsstats data agggregation" into rvc-dev

This commit is contained in:
Richard Gaywood
2020-04-16 18:43:09 +00:00
committed by Android (Google) Code Review
3 changed files with 137 additions and 22 deletions

View File

@@ -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]);
}
}

View File

@@ -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);
}
}

View File

@@ -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]};
}
}