diff --git a/core/java/com/android/internal/app/procstats/ProcessStats.java b/core/java/com/android/internal/app/procstats/ProcessStats.java index fb2337e447e44..35b53c2298bb2 100644 --- a/core/java/com/android/internal/app/procstats/ProcessStats.java +++ b/core/java/com/android/internal/app/procstats/ProcessStats.java @@ -43,6 +43,8 @@ import com.android.internal.app.procstats.DumpUtils.*; import dalvik.system.VMRuntime; import libcore.util.EmptyArray; +import java.io.BufferedReader; +import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; @@ -51,6 +53,8 @@ import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.Objects; +import java.util.regex.Pattern; +import java.util.regex.Matcher; public final class ProcessStats implements Parcelable { public static final String TAG = "ProcessStats"; @@ -151,7 +155,7 @@ public final class ProcessStats implements Parcelable { }; // Current version of the parcel format. - private static final int PARCEL_VERSION = 20; + private static final int PARCEL_VERSION = 21; // In-memory Parcel magic number, used to detect attempts to unmarshall bad data private static final int MAGIC = 0x50535454; @@ -188,6 +192,12 @@ public final class ProcessStats implements Parcelable { // For reading parcels. ArrayList mIndexToCommonString; + private static final Pattern sPageTypeRegex = Pattern.compile( + "^Node\\s+(\\d+),.*. type\\s+(\\w+)\\s+([\\s\\d]+?)\\s*$"); + private final ArrayList mPageTypeZones = new ArrayList(); + private final ArrayList mPageTypeLabels = new ArrayList(); + private final ArrayList mPageTypeSizes = new ArrayList(); + public ProcessStats(boolean running) { mRunning = running; reset(); @@ -493,6 +503,7 @@ public final class ProcessStats implements Parcelable { mReadError = null; mFlags = 0; evaluateSystemProperties(true); + updateFragmentation(); } public boolean evaluateSystemProperties(boolean update) { @@ -515,6 +526,101 @@ public final class ProcessStats implements Parcelable { static final int[] BAD_TABLE = new int[0]; + + /** + * Load the system's memory fragmentation info. + */ + public void updateFragmentation() { + // Parse /proc/pagetypeinfo and store the values. + BufferedReader reader = null; + try { + reader = new BufferedReader(new FileReader("/proc/pagetypeinfo")); + final Matcher matcher = sPageTypeRegex.matcher(""); + mPageTypeZones.clear(); + mPageTypeLabels.clear(); + mPageTypeSizes.clear(); + while (true) { + final String line = reader.readLine(); + if (line == null) { + break; + } + matcher.reset(line); + if (matcher.matches()) { + final Integer zone = Integer.valueOf(matcher.group(1), 10); + if (zone == null) { + continue; + } + mPageTypeZones.add(zone); + mPageTypeLabels.add(matcher.group(2)); + mPageTypeSizes.add(splitAndParseNumbers(matcher.group(3))); + } + } + } catch (IOException ex) { + mPageTypeZones.clear(); + mPageTypeLabels.clear(); + mPageTypeSizes.clear(); + return; + } finally { + if (reader != null) { + try { + reader.close(); + } catch (IOException allHopeIsLost) { + } + } + } + } + + /** + * Split the string of digits separaed by spaces. There must be no + * leading or trailing spaces. The format is ensured by the regex + * above. + */ + private static int[] splitAndParseNumbers(String s) { + // These are always positive and the numbers can't be so big that we'll overflow + // so just do the parsing inline. + boolean digit = false; + int count = 0; + final int N = s.length(); + // Count the numbers + for (int i=0; i= '0' && c <= '9') { + if (!digit) { + digit = true; + count++; + } + } else { + digit = false; + } + } + // Parse the numbers + final int[] result = new int[count]; + int p = 0; + int val = 0; + for (int i=0; i= '0' && c <= '9') { + if (!digit) { + digit = true; + val = c - '0'; + } else { + val *= 10; + val += c - '0'; + } + } else { + if (digit) { + digit = false; + result[p++] = val; + } + } + } + if (count > 0) { + result[count-1] = val; + } + return result; + } + + private void writeCompactedLongArray(Parcel out, long[] array, int num) { for (int i=0; i