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

Commit 125e4ec2 authored by Sudheer Shanka's avatar Sudheer Shanka Committed by Android (Google) Code Review
Browse files

Merge "check if per-uid cputimes proc file has correct no. of freqs."

parents 0e5366dc a5bca091
Loading
Loading
Loading
Loading
+33 −5
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
package com.android.internal.os;

import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
import static com.android.internal.os.KernelUidCpuFreqTimeReader.UID_TIMES_PROC_FILE;

import android.annotation.NonNull;
import android.util.Slog;
@@ -54,6 +55,12 @@ public class KernelSingleUidTimeReader {
    private boolean mSingleUidCpuTimesAvailable = true;
    @GuardedBy("this")
    private boolean mHasStaleData;
    // We use the freq count obtained from /proc/uid_time_in_state to decide how many longs
    // to read from each /proc/uid/<uid>/time_in_state. On the first read, verify if this is
    // correct and if not, set {@link #mSingleUidCpuTimesAvailable} to false. This flag will
    // indicate whether we checked for validity or not.
    @GuardedBy("this")
    private boolean mCpuFreqsCountVerified;

    private final Injector mInjector;

@@ -82,15 +89,15 @@ public class KernelSingleUidTimeReader {
            final String procFile = new StringBuilder(PROC_FILE_DIR)
                    .append(uid)
                    .append(PROC_FILE_NAME).toString();
            final long[] cpuTimesMs = new long[mCpuFreqsCount];
            final long[] cpuTimesMs;
            try {
                final byte[] data = mInjector.readData(procFile);
                if (!mCpuFreqsCountVerified) {
                    verifyCpuFreqsCount(data.length, procFile);
                }
                final ByteBuffer buffer = ByteBuffer.wrap(data);
                buffer.order(ByteOrder.nativeOrder());
                for (int i = 0; i < mCpuFreqsCount; ++i) {
                    // Times read will be in units of 10ms
                    cpuTimesMs[i] = buffer.getLong() * 10;
                }
                cpuTimesMs = readCpuTimesFromByteBuffer(buffer);
            } catch (Exception e) {
                if (++mReadErrorCounter >= TOTAL_READ_ERROR_COUNT) {
                    mSingleUidCpuTimesAvailable = false;
@@ -103,6 +110,27 @@ public class KernelSingleUidTimeReader {
        }
    }

    private void verifyCpuFreqsCount(int numBytes, String procFile) {
        final int actualCount = (numBytes / Long.BYTES);
        if (mCpuFreqsCount != actualCount) {
            mSingleUidCpuTimesAvailable = false;
            throw new IllegalStateException("Freq count didn't match,"
                    + "count from " + UID_TIMES_PROC_FILE + "=" + mCpuFreqsCount + ", but"
                    + "count from " + procFile + "=" + actualCount);
        }
        mCpuFreqsCountVerified = true;
    }

    private long[] readCpuTimesFromByteBuffer(ByteBuffer buffer) {
        final long[] cpuTimesMs;
        cpuTimesMs = new long[mCpuFreqsCount];
        for (int i = 0; i < mCpuFreqsCount; ++i) {
            // Times read will be in units of 10ms
            cpuTimesMs[i] = buffer.getLong() * 10;
        }
        return cpuTimesMs;
    }

    /**
     * Compute and return cpu times delta of an uid using previously read cpu times and
     * {@param latestCpuTimesMs}.
+1 −1
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ import java.io.IOException;
public class KernelUidCpuFreqTimeReader {
    private static final boolean DEBUG = false;
    private static final String TAG = "KernelUidCpuFreqTimeReader";
    private static final String UID_TIMES_PROC_FILE = "/proc/uid_time_in_state";
    static final String UID_TIMES_PROC_FILE = "/proc/uid_time_in_state";

    public interface Callback {
        void onUidCpuFreqTime(int uid, long[] cpuFreqTimeMs);
+24 −0
Original line number Diff line number Diff line
@@ -114,6 +114,30 @@ public class KernelSingleUidTimeReaderTest {
        assertFalse(mReader.singleUidCpuTimesAvailable());
    }

    @Test
    public void readDelta_incorrectCount() {
        assertTrue(mReader.singleUidCpuTimesAvailable());

        long[] cpuTimes = new long[TEST_FREQ_COUNT - 1];
        for (int i = 0; i < cpuTimes.length; ++i) {
            cpuTimes[i] = 111 + i;
        }
        mInjector.setData(cpuTimes);
        assertCpuTimesEqual(null, mReader.readDeltaMs(TEST_UID));
        assertFalse(mReader.singleUidCpuTimesAvailable());

        // Reset
        mReader.setSingleUidCpuTimesAvailable(true);

        cpuTimes = new long[TEST_FREQ_COUNT + 1];
        for (int i = 0; i < cpuTimes.length; ++i) {
            cpuTimes[i] = 222 + i;
        }
        mInjector.setData(cpuTimes);
        assertCpuTimesEqual(null, mReader.readDeltaMs(TEST_UID));
        assertFalse(mReader.singleUidCpuTimesAvailable());
    }

    @Test
    public void testComputeDelta() {
        // proc file not available