Loading core/java/com/android/internal/os/KernelCpuProcReader.java +27 −31 Original line number Diff line number Diff line Loading @@ -24,13 +24,14 @@ import com.android.internal.annotations.VisibleForTesting; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.channels.FileChannel; import java.nio.file.Files; import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.util.Arrays; /** * Reads cpu time proc files with throttling (adjustable interval). Loading @@ -55,7 +56,6 @@ public class KernelCpuProcReader { private static final int ERROR_THRESHOLD = 5; // Throttle interval in milliseconds private static final long DEFAULT_THROTTLE_INTERVAL = 3000L; private static final int INITIAL_BUFFER_SIZE = 8 * 1024; private static final int MAX_BUFFER_SIZE = 1024 * 1024; private static final String PROC_UID_FREQ_TIME = "/proc/uid_cpupower/time_in_state"; private static final String PROC_UID_ACTIVE_TIME = "/proc/uid_cpupower/concurrent_active_time"; Loading Loading @@ -84,13 +84,12 @@ public class KernelCpuProcReader { private long mThrottleInterval = DEFAULT_THROTTLE_INTERVAL; private long mLastReadTime = Long.MIN_VALUE; private final Path mProc; private ByteBuffer mBuffer; private byte[] mBuffer = new byte[8 * 1024]; private int mContentSize; @VisibleForTesting public KernelCpuProcReader(String procFile) { mProc = Paths.get(procFile); mBuffer = ByteBuffer.allocateDirect(INITIAL_BUFFER_SIZE); mBuffer.clear(); } /** Loading @@ -108,38 +107,45 @@ public class KernelCpuProcReader { return null; } if (SystemClock.elapsedRealtime() < mLastReadTime + mThrottleInterval) { if (mBuffer.limit() > 0 && mBuffer.limit() < mBuffer.capacity()) { // mBuffer has data. return mBuffer.asReadOnlyBuffer().order(ByteOrder.nativeOrder()); if (mContentSize > 0) { return ByteBuffer.wrap(mBuffer, 0, mContentSize).asReadOnlyBuffer() .order(ByteOrder.nativeOrder()); } return null; } mLastReadTime = SystemClock.elapsedRealtime(); mBuffer.clear(); mContentSize = 0; final int oldMask = StrictMode.allowThreadDiskReadsMask(); try (FileChannel fc = FileChannel.open(mProc, StandardOpenOption.READ)) { while (fc.read(mBuffer) == mBuffer.capacity()) { if (!resize()) { try (InputStream in = Files.newInputStream(mProc)) { int numBytes = 0; int curr; while ((curr = in.read(mBuffer, numBytes, mBuffer.length - numBytes)) >= 0) { numBytes += curr; if (numBytes == mBuffer.length) { // Hit the limit. Resize mBuffer. if (mBuffer.length == MAX_BUFFER_SIZE) { mErrors++; Slog.e(TAG, "Proc file is too large: " + mProc); return null; } fc.position(0); mBuffer = Arrays.copyOf(mBuffer, Math.min(mBuffer.length << 1, MAX_BUFFER_SIZE)); } } mContentSize = numBytes; return ByteBuffer.wrap(mBuffer, 0, mContentSize).asReadOnlyBuffer() .order(ByteOrder.nativeOrder()); } catch (NoSuchFileException | FileNotFoundException e) { // Happens when the kernel does not provide this file. Not a big issue. Just log it. mErrors++; Slog.w(TAG, "File not exist: " + mProc); return null; } catch (IOException e) { mErrors++; Slog.e(TAG, "Error reading: " + mProc, e); return null; } finally { StrictMode.setThreadPolicyMask(oldMask); } mBuffer.flip(); return mBuffer.asReadOnlyBuffer().order(ByteOrder.nativeOrder()); return null; } /** Loading @@ -153,14 +159,4 @@ public class KernelCpuProcReader { mThrottleInterval = throttleInterval; } } private boolean resize() { if (mBuffer.capacity() >= MAX_BUFFER_SIZE) { return false; } int newSize = Math.min(mBuffer.capacity() << 1, MAX_BUFFER_SIZE); // Slog.i(TAG, "Resize buffer " + mBuffer.capacity() + " => " + newSize); mBuffer = ByteBuffer.allocateDirect(newSize); return true; } } Loading
core/java/com/android/internal/os/KernelCpuProcReader.java +27 −31 Original line number Diff line number Diff line Loading @@ -24,13 +24,14 @@ import com.android.internal.annotations.VisibleForTesting; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.channels.FileChannel; import java.nio.file.Files; import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.util.Arrays; /** * Reads cpu time proc files with throttling (adjustable interval). Loading @@ -55,7 +56,6 @@ public class KernelCpuProcReader { private static final int ERROR_THRESHOLD = 5; // Throttle interval in milliseconds private static final long DEFAULT_THROTTLE_INTERVAL = 3000L; private static final int INITIAL_BUFFER_SIZE = 8 * 1024; private static final int MAX_BUFFER_SIZE = 1024 * 1024; private static final String PROC_UID_FREQ_TIME = "/proc/uid_cpupower/time_in_state"; private static final String PROC_UID_ACTIVE_TIME = "/proc/uid_cpupower/concurrent_active_time"; Loading Loading @@ -84,13 +84,12 @@ public class KernelCpuProcReader { private long mThrottleInterval = DEFAULT_THROTTLE_INTERVAL; private long mLastReadTime = Long.MIN_VALUE; private final Path mProc; private ByteBuffer mBuffer; private byte[] mBuffer = new byte[8 * 1024]; private int mContentSize; @VisibleForTesting public KernelCpuProcReader(String procFile) { mProc = Paths.get(procFile); mBuffer = ByteBuffer.allocateDirect(INITIAL_BUFFER_SIZE); mBuffer.clear(); } /** Loading @@ -108,38 +107,45 @@ public class KernelCpuProcReader { return null; } if (SystemClock.elapsedRealtime() < mLastReadTime + mThrottleInterval) { if (mBuffer.limit() > 0 && mBuffer.limit() < mBuffer.capacity()) { // mBuffer has data. return mBuffer.asReadOnlyBuffer().order(ByteOrder.nativeOrder()); if (mContentSize > 0) { return ByteBuffer.wrap(mBuffer, 0, mContentSize).asReadOnlyBuffer() .order(ByteOrder.nativeOrder()); } return null; } mLastReadTime = SystemClock.elapsedRealtime(); mBuffer.clear(); mContentSize = 0; final int oldMask = StrictMode.allowThreadDiskReadsMask(); try (FileChannel fc = FileChannel.open(mProc, StandardOpenOption.READ)) { while (fc.read(mBuffer) == mBuffer.capacity()) { if (!resize()) { try (InputStream in = Files.newInputStream(mProc)) { int numBytes = 0; int curr; while ((curr = in.read(mBuffer, numBytes, mBuffer.length - numBytes)) >= 0) { numBytes += curr; if (numBytes == mBuffer.length) { // Hit the limit. Resize mBuffer. if (mBuffer.length == MAX_BUFFER_SIZE) { mErrors++; Slog.e(TAG, "Proc file is too large: " + mProc); return null; } fc.position(0); mBuffer = Arrays.copyOf(mBuffer, Math.min(mBuffer.length << 1, MAX_BUFFER_SIZE)); } } mContentSize = numBytes; return ByteBuffer.wrap(mBuffer, 0, mContentSize).asReadOnlyBuffer() .order(ByteOrder.nativeOrder()); } catch (NoSuchFileException | FileNotFoundException e) { // Happens when the kernel does not provide this file. Not a big issue. Just log it. mErrors++; Slog.w(TAG, "File not exist: " + mProc); return null; } catch (IOException e) { mErrors++; Slog.e(TAG, "Error reading: " + mProc, e); return null; } finally { StrictMode.setThreadPolicyMask(oldMask); } mBuffer.flip(); return mBuffer.asReadOnlyBuffer().order(ByteOrder.nativeOrder()); return null; } /** Loading @@ -153,14 +159,4 @@ public class KernelCpuProcReader { mThrottleInterval = throttleInterval; } } private boolean resize() { if (mBuffer.capacity() >= MAX_BUFFER_SIZE) { return false; } int newSize = Math.min(mBuffer.capacity() << 1, MAX_BUFFER_SIZE); // Slog.i(TAG, "Resize buffer " + mBuffer.capacity() + " => " + newSize); mBuffer = ByteBuffer.allocateDirect(newSize); return true; } }