summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/os/KernelCpuProcReader.java58
1 files changed, 27 insertions, 31 deletions
diff --git a/core/java/com/android/internal/os/KernelCpuProcReader.java b/core/java/com/android/internal/os/KernelCpuProcReader.java
index 396deb4d7a0a..c233ea8e78b7 100644
--- a/core/java/com/android/internal/os/KernelCpuProcReader.java
+++ b/core/java/com/android/internal/os/KernelCpuProcReader.java
@@ -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).
@@ -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";
@@ -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();
}
/**
@@ -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()) {
- mErrors++;
- Slog.e(TAG, "Proc file is too large: " + mProc);
- return null;
+ 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;
+ }
+ mBuffer = Arrays.copyOf(mBuffer,
+ Math.min(mBuffer.length << 1, MAX_BUFFER_SIZE));
}
- fc.position(0);
}
+ 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;
}
/**
@@ -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;
- }
}