Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 69d8b3e0 authored by Mike Ma's avatar Mike Ma
Browse files

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
parent 5622f475
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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
+11 −23
Original line number Diff line number Diff line
@@ -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);
            if (DEBUG) {
                Slog.d(TAG, "Read uids: " + numUids);
            }
        mLastTimeReadMs = SystemClock.elapsedRealtime();
    }

    public void setThrottleInterval(long throttleInterval) {
        if (throttleInterval >= 0) {
            mThrottleInterval = throttleInterval;
        }
    }

+13 −25
Original line number Diff line number Diff line
@@ -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) {
+13 −23
Original line number Diff line number Diff line
@@ -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);
            }
        }
    }

+18 −9
Original line number Diff line number Diff line
@@ -38,15 +38,16 @@ 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
@@ -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,7 +151,10 @@ 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
     */
Loading