Merge "Implement procsstats data agggregation" into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
89e6a4a4b5
@@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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]};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user