diff options
| author | 2018-02-23 14:51:26 -0800 | |
|---|---|---|
| committer | 2018-02-26 15:39:52 -0800 | |
| commit | 69d8b3e0508de7e181f70a3322be626b1527ee0e (patch) | |
| tree | d89e46cacb20d305728291ecbb581105252ed008 | |
| parent | 5622f47532193c9eea7f549c5bf431df2db13884 (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
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; + } + } +} |