Merge "Implement procsstats data agggregation" into rvc-dev am: 89e6a4a4b5 am: ffea2256b9
Change-Id: I808156c9fa8599f2de1777a16fa8985742afe643
This commit is contained in:
@@ -539,4 +539,11 @@ public final class DumpUtils {
|
|||||||
// Pack screen & process state using bit shifting
|
// Pack screen & process state using bit shifting
|
||||||
return (procStateIndex << 8) | screenStateIndex;
|
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;
|
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_AVERAGE;
|
||||||
import static com.android.internal.app.procstats.ProcessStats.PSS_COUNT;
|
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_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_SERVICE_RESTARTING;
|
||||||
import static com.android.internal.app.procstats.ProcessStats.STATE_TOP;
|
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.PackageState;
|
||||||
import com.android.internal.app.procstats.ProcessStats.ProcessStateHolder;
|
import com.android.internal.app.procstats.ProcessStats.ProcessStateHolder;
|
||||||
import com.android.internal.app.procstats.ProcessStats.TotalMemoryUseCollection;
|
import com.android.internal.app.procstats.ProcessStats.TotalMemoryUseCollection;
|
||||||
@@ -1418,4 +1417,108 @@ public final class ProcessState {
|
|||||||
|
|
||||||
proto.end(token);
|
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;
|
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_AVERAGE;
|
||||||
import static com.android.internal.app.procstats.ProcessStats.PSS_RSS_MAXIMUM;
|
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_RSS_MINIMUM;
|
||||||
import static com.android.internal.app.procstats.ProcessStats.PSS_SAMPLE_COUNT;
|
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_AVERAGE;
|
||||||
import static com.android.internal.app.procstats.ProcessStats.PSS_USS_MAXIMUM;
|
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.service.procstats.ProcessStatsStateProto;
|
||||||
import android.util.proto.ProtoOutputStream;
|
import android.util.proto.ProtoOutputStream;
|
||||||
@@ -133,7 +133,6 @@ public class PssTable extends SparseMappingTable.Table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (stats[statsIndex + PSS_RSS_MINIMUM] > minRss) {
|
if (stats[statsIndex + PSS_RSS_MINIMUM] > minRss) {
|
||||||
stats[statsIndex + PSS_RSS_MINIMUM] = minRss;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stats[statsIndex + PSS_RSS_AVERAGE] = (long)(((stats[statsIndex + PSS_RSS_AVERAGE]
|
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_AVERAGE],
|
||||||
stats[statsIndex + PSS_RSS_MAXIMUM]);
|
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