summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mike Ma <yanmin@google.com> 2018-02-23 14:51:26 -0800
committer Mike Ma <yanmin@google.com> 2018-02-26 15:39:52 -0800
commit69d8b3e0508de7e181f70a3322be626b1527ee0e (patch)
treed89e46cacb20d305728291ecbb581105252ed008
parent5622f47532193c9eea7f549c5bf431df2db13884 (diff)
Refactor KernelUidCpuTimeReader
Refactor KernelUidCpu*TimeReader, all extends KernelUidCpuTimeReaderBase. Refined logging of these classes, avoid spamming system log. Change-Id: Id8e149ce5be2595292a31de7fe6e1a94cef28bc1 Fixes: 73825907 Test: KernelUidCpu*TimeReaderTest
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java1
-rw-r--r--core/java/com/android/internal/os/KernelUidCpuActiveTimeReader.java34
-rw-r--r--core/java/com/android/internal/os/KernelUidCpuClusterTimeReader.java38
-rw-r--r--core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java36
-rw-r--r--core/java/com/android/internal/os/KernelUidCpuTimeReader.java27
-rw-r--r--core/java/com/android/internal/os/KernelUidCpuTimeReaderBase.java60
6 files changed, 116 insertions, 80 deletions
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 5966a8665f41..1a6cdfe9d092 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -13438,6 +13438,7 @@ public class BatteryStatsImpl extends BatteryStats {
private void updateKernelUidReadersThrottleTime(long oldTimeMs, long newTimeMs) {
KERNEL_UID_READERS_THROTTLE_TIME = newTimeMs;
if (oldTimeMs != newTimeMs) {
+ mKernelUidCpuTimeReader.setThrottleInterval(KERNEL_UID_READERS_THROTTLE_TIME);
mKernelUidCpuFreqTimeReader.setThrottleInterval(KERNEL_UID_READERS_THROTTLE_TIME);
mKernelUidCpuActiveTimeReader.setThrottleInterval(KERNEL_UID_READERS_THROTTLE_TIME);
mKernelUidCpuClusterTimeReader
diff --git a/core/java/com/android/internal/os/KernelUidCpuActiveTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuActiveTimeReader.java
index 2519412f3246..ce45f3c988cb 100644
--- a/core/java/com/android/internal/os/KernelUidCpuActiveTimeReader.java
+++ b/core/java/com/android/internal/os/KernelUidCpuActiveTimeReader.java
@@ -17,7 +17,6 @@
package com.android.internal.os;
import android.annotation.Nullable;
-import android.os.SystemClock;
import android.util.Slog;
import android.util.SparseArray;
@@ -46,20 +45,17 @@ import java.nio.IntBuffer;
* which has a shorter throttle interval and returns cached result from last read when the request
* is throttled.
*
- * This class is NOT thread-safe and NOT designed to be accessed by more than one caller (due to
- * the nature of {@link #readDelta(Callback)}).
+ * This class is NOT thread-safe and NOT designed to be accessed by more than one caller since each
+ * caller has its own view of delta.
*/
-public class KernelUidCpuActiveTimeReader {
- private static final String TAG = "KernelUidCpuActiveTimeReader";
- // Throttle interval in milliseconds
- private static final long DEFAULT_THROTTLE_INTERVAL = 10_000L;
+public class KernelUidCpuActiveTimeReader extends
+ KernelUidCpuTimeReaderBase<KernelUidCpuActiveTimeReader.Callback> {
+ private static final String TAG = KernelUidCpuActiveTimeReader.class.getSimpleName();
private final KernelCpuProcReader mProcReader;
- private long mLastTimeReadMs = Long.MIN_VALUE;
- private long mThrottleInterval = DEFAULT_THROTTLE_INTERVAL;
private SparseArray<Double> mLastUidCpuActiveTimeMs = new SparseArray<>();
- public interface Callback {
+ public interface Callback extends KernelUidCpuTimeReaderBase.Callback {
/**
* Notifies when new data is available.
*
@@ -78,11 +74,8 @@ public class KernelUidCpuActiveTimeReader {
mProcReader = procReader;
}
- public void readDelta(@Nullable Callback cb) {
- if (SystemClock.elapsedRealtime() < mLastTimeReadMs + mThrottleInterval) {
- Slog.w(TAG, "Throttle");
- return;
- }
+ @Override
+ protected void readDeltaImpl(@Nullable Callback cb) {
synchronized (mProcReader) {
final ByteBuffer bytes = mProcReader.readBytes();
if (bytes == null || bytes.remaining() <= 4) {
@@ -124,14 +117,9 @@ public class KernelUidCpuActiveTimeReader {
}
}
}
- // Slog.i(TAG, "Read uids: " + numUids);
- }
- mLastTimeReadMs = SystemClock.elapsedRealtime();
- }
-
- public void setThrottleInterval(long throttleInterval) {
- if (throttleInterval >= 0) {
- mThrottleInterval = throttleInterval;
+ if (DEBUG) {
+ Slog.d(TAG, "Read uids: " + numUids);
+ }
}
}
diff --git a/core/java/com/android/internal/os/KernelUidCpuClusterTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuClusterTimeReader.java
index 41ef8f05f0d1..c21b7665c7ae 100644
--- a/core/java/com/android/internal/os/KernelUidCpuClusterTimeReader.java
+++ b/core/java/com/android/internal/os/KernelUidCpuClusterTimeReader.java
@@ -17,7 +17,6 @@
package com.android.internal.os;
import android.annotation.Nullable;
-import android.os.SystemClock;
import android.util.Slog;
import android.util.SparseArray;
@@ -50,17 +49,14 @@ import java.nio.IntBuffer;
* which has a shorter throttle interval and returns cached result from last read when the request
* is throttled.
*
- * This class is NOT thread-safe and NOT designed to be accessed by more than one caller (due to
- * the nature of {@link #readDelta(Callback)}).
+ * This class is NOT thread-safe and NOT designed to be accessed by more than one caller since each
+ * caller has its own view of delta.
*/
-public class KernelUidCpuClusterTimeReader {
- private static final String TAG = "KernelUidCpuClusterTimeReader";
- // Throttle interval in milliseconds
- private static final long DEFAULT_THROTTLE_INTERVAL = 10_000L;
+public class KernelUidCpuClusterTimeReader extends
+ KernelUidCpuTimeReaderBase<KernelUidCpuClusterTimeReader.Callback> {
+ private static final String TAG = KernelUidCpuClusterTimeReader.class.getSimpleName();
private final KernelCpuProcReader mProcReader;
- private long mLastTimeReadMs = Long.MIN_VALUE;
- private long mThrottleInterval = DEFAULT_THROTTLE_INTERVAL;
private SparseArray<double[]> mLastUidPolicyTimeMs = new SparseArray<>();
private int mNumClusters = -1;
@@ -70,7 +66,7 @@ public class KernelUidCpuClusterTimeReader {
private double[] mCurTime; // Reuse to avoid GC.
private long[] mDeltaTime; // Reuse to avoid GC.
- public interface Callback {
+ public interface Callback extends KernelUidCpuTimeReaderBase.Callback {
/**
* Notifies when new data is available.
*
@@ -90,17 +86,8 @@ public class KernelUidCpuClusterTimeReader {
mProcReader = procReader;
}
- public void setThrottleInterval(long throttleInterval) {
- if (throttleInterval >= 0) {
- mThrottleInterval = throttleInterval;
- }
- }
-
- public void readDelta(@Nullable Callback cb) {
- if (SystemClock.elapsedRealtime() < mLastTimeReadMs + mThrottleInterval) {
- Slog.w(TAG, "Throttle");
- return;
- }
+ @Override
+ protected void readDeltaImpl(@Nullable Callback cb) {
synchronized (mProcReader) {
ByteBuffer bytes = mProcReader.readBytes();
if (bytes == null || bytes.remaining() <= 4) {
@@ -142,14 +129,15 @@ public class KernelUidCpuClusterTimeReader {
int numUids = buf.remaining() / (mNumCores + 1);
for (int i = 0; i < numUids; i++) {
- processUidLocked(buf, cb);
+ processUid(buf, cb);
+ }
+ if (DEBUG) {
+ Slog.d(TAG, "Read uids: " + numUids);
}
- // Slog.i(TAG, "Read uids: " + numUids);
}
- mLastTimeReadMs = SystemClock.elapsedRealtime();
}
- private void processUidLocked(IntBuffer buf, @Nullable Callback cb) {
+ private void processUid(IntBuffer buf, @Nullable Callback cb) {
int uid = buf.get();
double[] lastTimes = mLastUidPolicyTimeMs.get(uid);
if (lastTimes == null) {
diff --git a/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java
index a21a70e1d2c9..a0787a039dbe 100644
--- a/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java
+++ b/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java
@@ -59,24 +59,21 @@ import java.nio.IntBuffer;
* which has a shorter throttle interval and returns cached result from last read when the request
* is throttled.
*
- * This class is NOT thread-safe and NOT designed to be accessed by more than one caller (due to
- * the nature of {@link #readDelta(Callback)}).
+ * This class is NOT thread-safe and NOT designed to be accessed by more than one caller since each
+ * caller has its own view of delta.
*/
-public class KernelUidCpuFreqTimeReader {
- private static final boolean DEBUG = false;
- private static final String TAG = "KernelUidCpuFreqTimeReader";
+public class KernelUidCpuFreqTimeReader extends
+ KernelUidCpuTimeReaderBase<KernelUidCpuFreqTimeReader.Callback> {
+ private static final String TAG = KernelUidCpuFreqTimeReader.class.getSimpleName();
static final String UID_TIMES_PROC_FILE = "/proc/uid_time_in_state";
- // Throttle interval in milliseconds
- private static final long DEFAULT_THROTTLE_INTERVAL = 10_000L;
- public interface Callback {
+ public interface Callback extends KernelUidCpuTimeReaderBase.Callback {
void onUidCpuFreqTime(int uid, long[] cpuFreqTimeMs);
}
private long[] mCpuFreqs;
private long[] mCurTimes; // Reuse to prevent GC.
private long[] mDeltaTimes; // Reuse to prevent GC.
- private long mThrottleInterval = DEFAULT_THROTTLE_INTERVAL;
private int mCpuFreqsCount;
private long mLastTimeReadMs = Long.MIN_VALUE;
private long mNowTimeMs;
@@ -150,30 +147,20 @@ public class KernelUidCpuFreqTimeReader {
mReadBinary = readBinary;
}
- public void setThrottleInterval(long throttleInterval) {
- if (throttleInterval >= 0) {
- mThrottleInterval = throttleInterval;
- }
- }
-
- public void readDelta(@Nullable Callback callback) {
+ @Override
+ protected void readDeltaImpl(@Nullable Callback callback) {
if (mCpuFreqs == null) {
return;
}
- if (SystemClock.elapsedRealtime() < mLastTimeReadMs + mThrottleInterval) {
- Slog.w(TAG, "Throttle");
- return;
- }
- mNowTimeMs = SystemClock.elapsedRealtime();
if (mReadBinary) {
readDeltaBinary(callback);
} else {
readDeltaString(callback);
}
- mLastTimeReadMs = mNowTimeMs;
}
private void readDeltaString(@Nullable Callback callback) {
+ mNowTimeMs = SystemClock.elapsedRealtime();
final int oldMask = StrictMode.allowThreadDiskReadsMask();
try (BufferedReader reader = new BufferedReader(new FileReader(UID_TIMES_PROC_FILE))) {
readDelta(reader, callback);
@@ -182,6 +169,7 @@ public class KernelUidCpuFreqTimeReader {
} finally {
StrictMode.setThreadPolicyMask(oldMask);
}
+ mLastTimeReadMs = mNowTimeMs;
}
@VisibleForTesting
@@ -232,7 +220,9 @@ public class KernelUidCpuFreqTimeReader {
}
}
}
- // Slog.i(TAG, "Read uids: "+numUids);
+ if (DEBUG) {
+ Slog.d(TAG, "Read uids: " + numUids);
+ }
}
}
diff --git a/core/java/com/android/internal/os/KernelUidCpuTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
index 444049e7e415..4263b832bd4f 100644
--- a/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
+++ b/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
@@ -38,18 +38,19 @@ import java.io.IOException;
* maintains the previous results of a call to {@link #readDelta} in order to provide a proper
* delta.
*/
-public class KernelUidCpuTimeReader {
- private static final String TAG = "KernelUidCpuTimeReader";
+public class KernelUidCpuTimeReader extends
+ KernelUidCpuTimeReaderBase<KernelUidCpuTimeReader.Callback> {
+ private static final String TAG = KernelUidCpuTimeReader.class.getSimpleName();
private static final String sProcFile = "/proc/uid_cputime/show_uid_stat";
private static final String sRemoveUidProcFile = "/proc/uid_cputime/remove_uid_range";
/**
* Callback interface for processing each line of the proc file.
*/
- public interface Callback {
+ public interface Callback extends KernelUidCpuTimeReaderBase.Callback {
/**
- * @param uid UID of the app
- * @param userTimeUs time spent executing in user space in microseconds
+ * @param uid UID of the app
+ * @param userTimeUs time spent executing in user space in microseconds
* @param systemTimeUs time spent executing in kernel space in microseconds
*/
void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs);
@@ -61,11 +62,13 @@ public class KernelUidCpuTimeReader {
/**
* Reads the proc file, calling into the callback with a delta of time for each UID.
+ *
* @param callback The callback to invoke for each line of the proc file. If null,
* the data is consumed and subsequent calls to readDelta will provide
* a fresh delta.
*/
- public void readDelta(@Nullable Callback callback) {
+ @Override
+ protected void readDeltaImpl(@Nullable Callback callback) {
final int oldMask = StrictMode.allowThreadDiskReadsMask();
long nowUs = SystemClock.elapsedRealtime() * 1000;
try (BufferedReader reader = new BufferedReader(new FileReader(sProcFile))) {
@@ -132,7 +135,10 @@ public class KernelUidCpuTimeReader {
}
/**
- * Removes the UID from the kernel module and from internal accounting data.
+ * Removes the UID from the kernel module and from internal accounting data. Only
+ * {@link BatteryStatsImpl} and its child processes should call this, as the change on Kernel is
+ * visible system wide.
+ *
* @param uid The UID to remove.
*/
public void removeUid(int uid) {
@@ -145,9 +151,12 @@ public class KernelUidCpuTimeReader {
}
/**
- * Removes UIDs in a given range from the kernel module and internal accounting data.
+ * Removes UIDs in a given range from the kernel module and internal accounting data. Only
+ * {@link BatteryStatsImpl} and its child processes should call this, as the change on Kernel is
+ * visible system wide.
+ *
* @param startUid the first uid to remove
- * @param endUid the last uid to remove
+ * @param endUid the last uid to remove
*/
public void removeUidsInRange(int startUid, int endUid) {
if (endUid < startUid) {
diff --git a/core/java/com/android/internal/os/KernelUidCpuTimeReaderBase.java b/core/java/com/android/internal/os/KernelUidCpuTimeReaderBase.java
new file mode 100644
index 000000000000..11e50e1ecb95
--- /dev/null
+++ b/core/java/com/android/internal/os/KernelUidCpuTimeReaderBase.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.os;
+
+import android.annotation.Nullable;
+import android.os.SystemClock;
+import android.util.Slog;
+
+/**
+ * The base class of all KernelUidCpuTimeReaders.
+ *
+ * This class is NOT designed to be thread-safe or accessed by more than one caller (due to
+ * the nature of {@link #readDelta(Callback)}).
+ */
+public abstract class KernelUidCpuTimeReaderBase<T extends KernelUidCpuTimeReaderBase.Callback> {
+ protected static final boolean DEBUG = false;
+ // Throttle interval in milliseconds
+ private static final long DEFAULT_THROTTLE_INTERVAL = 10_000L;
+
+ private final String TAG = this.getClass().getSimpleName();
+ private long mLastTimeReadMs = Long.MIN_VALUE;
+ private long mThrottleInterval = DEFAULT_THROTTLE_INTERVAL;
+
+ // A generic Callback interface (used by readDelta) to be extended by subclasses.
+ public interface Callback {
+ }
+
+ public void readDelta(@Nullable T cb) {
+ if (SystemClock.elapsedRealtime() < mLastTimeReadMs + mThrottleInterval) {
+ if (DEBUG) {
+ Slog.d(TAG, "Throttle");
+ }
+ return;
+ }
+ readDeltaImpl(cb);
+ mLastTimeReadMs = SystemClock.elapsedRealtime();
+ }
+
+ protected abstract void readDeltaImpl(@Nullable T cb);
+
+ public void setThrottleInterval(long throttleInterval) {
+ if (throttleInterval >= 0) {
+ mThrottleInterval = throttleInterval;
+ }
+ }
+}