Track max CPU and latency of binder calls
Test: unit tested
Change-Id: I1429e8c34e9cb0572975fda3ec18e85d6caf3cad
diff --git a/core/java/com/android/internal/os/BinderCallsStats.java b/core/java/com/android/internal/os/BinderCallsStats.java
index fbb99e4..75d714f 100644
--- a/core/java/com/android/internal/os/BinderCallsStats.java
+++ b/core/java/com/android/internal/os/BinderCallsStats.java
@@ -122,25 +122,25 @@
mUidEntries.put(callingUid, uidEntry);
}
+ CallStat callStat;
if (mDetailedTracking) {
// Find CallStat entry and update its total time
- CallStat callStat = uidEntry.getOrCreate(s.callStat);
- callStat.callCount++;
- callStat.cpuTimeMicros += duration;
- callStat.latencyMicros += latencyDuration;
+ callStat = uidEntry.getOrCreate(s.callStat);
callStat.exceptionCount += s.exceptionThrown ? 1 : 0;
- callStat.maxLatencyMicros = Math.max(callStat.maxLatencyMicros, latencyDuration);
callStat.maxRequestSizeBytes =
Math.max(callStat.maxRequestSizeBytes, parcelRequestSize);
callStat.maxReplySizeBytes =
Math.max(callStat.maxReplySizeBytes, parcelReplySize);
} else {
// update sampled timings in the beginning of each interval
- if (s.cpuTimeStarted >= 0) {
- s.sampledCallStat.cpuTimeMicros += duration;
- s.sampledCallStat.latencyMicros += latencyDuration;
- }
- s.sampledCallStat.callCount++;
+ callStat = s.sampledCallStat;
+ }
+ callStat.callCount++;
+ if (s.cpuTimeStarted >= 0) {
+ callStat.cpuTimeMicros += duration;
+ callStat.maxCpuTimeMicros = Math.max(callStat.maxCpuTimeMicros, duration);
+ callStat.latencyMicros += latencyDuration;
+ callStat.maxLatencyMicros = Math.max(callStat.maxLatencyMicros, latencyDuration);
}
uidEntry.cpuTimeMicros += duration;
@@ -189,7 +189,7 @@
StringBuilder sb = new StringBuilder();
if (mDetailedTracking) {
pw.println("Per-UID raw data " + datasetSizeDesc
- + "(uid, call_desc, cpu_time_micros, latency_time_micros, "
+ + "(uid, call_desc, cpu_time_micros, max_cpu_time_micros, latency_time_micros, "
+ "max_latency_time_micros, exception_count, max_request_size_bytes, "
+ "max_reply_size_bytes, call_count):");
List<UidEntry> topEntries = verbose ? entries
@@ -200,6 +200,7 @@
sb.append(" ")
.append(uidEntry.uid).append(",").append(e)
.append(',').append(e.cpuTimeMicros)
+ .append(',').append(e.maxCpuTimeMicros)
.append(',').append(e.latencyMicros)
.append(',').append(e.maxLatencyMicros)
.append(',').append(e.exceptionCount)
@@ -260,7 +261,7 @@
return Binder.getCallingUid();
}
- private long getElapsedRealtimeMicro() {
+ protected long getElapsedRealtimeMicro() {
return SystemClock.elapsedRealtimeNanos() / 1000;
}
@@ -288,11 +289,13 @@
public String className;
public int msg;
public long cpuTimeMicros;
+ public long maxCpuTimeMicros;
public long latencyMicros;
public long maxLatencyMicros;
+ public long callCount;
+ // The following fields are only computed if mDetailedTracking is set.
public long maxRequestSizeBytes;
public long maxReplySizeBytes;
- public long callCount;
public long exceptionCount;
CallStat() {
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
index b7fef13..18263ab 100644
--- a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
@@ -155,6 +155,42 @@
}
@Test
+ public void testMaxCpu() {
+ TestBinderCallsStats bcs = new TestBinderCallsStats(true);
+ Binder binder = new Binder();
+ BinderCallsStats.CallSession callSession = bcs.callStarted(binder, 1);
+ bcs.time += 50;
+ bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+
+ callSession = bcs.callStarted(binder, 1);
+ bcs.time += 10;
+ bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+
+ List<BinderCallsStats.CallStat> callStatsList =
+ bcs.getUidEntries().get(TEST_UID).getCallStatsList();
+
+ assertEquals(50, callStatsList.get(0).maxCpuTimeMicros);
+ }
+
+ @Test
+ public void testMaxLatency() {
+ TestBinderCallsStats bcs = new TestBinderCallsStats(true);
+ Binder binder = new Binder();
+ BinderCallsStats.CallSession callSession = bcs.callStarted(binder, 1);
+ bcs.elapsedTime += 5;
+ bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+
+ callSession = bcs.callStarted(binder, 1);
+ bcs.elapsedTime += 1;
+ bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+
+ List<BinderCallsStats.CallStat> callStatsList =
+ bcs.getUidEntries().get(TEST_UID).getCallStatsList();
+
+ assertEquals(5, callStatsList.get(0).maxLatencyMicros);
+ }
+
+ @Test
public void testGetHighestValues() {
List<Integer> list = Arrays.asList(1, 2, 3, 4);
List<Integer> highestValues = BinderCallsStats
@@ -165,6 +201,7 @@
static class TestBinderCallsStats extends BinderCallsStats {
int callingUid = TEST_UID;
long time = 1234;
+ long elapsedTime = 0;
TestBinderCallsStats(boolean detailedTracking) {
super(detailedTracking);
@@ -176,6 +213,11 @@
}
@Override
+ protected long getElapsedRealtimeMicro() {
+ return elapsedTime;
+ }
+
+ @Override
protected int getCallingUid() {
return callingUid;
}