1 package com.android.internal.os; 2 3 import android.os.StrictMode; 4 import android.text.TextUtils; 5 import android.util.LongSparseLongArray; 6 import android.util.Slog; 7 8 import com.android.internal.annotations.VisibleForTesting; 9 10 import java.io.BufferedReader; 11 import java.io.FileNotFoundException; 12 import java.io.FileReader; 13 import java.io.IOException; 14 15 /** 16 * Reads DDR time spent at various frequencies and stores the data. Supports diff comparison with 17 * other KernelMemoryBandwidthStats objects. The sysfs file has the format: 18 * 19 * freq time_in_bucket ... time_in_bucket 20 * ... 21 * freq time_in_bucket ... time_in_bucket 22 * 23 * where time is measured in nanoseconds. 24 */ 25 public class KernelMemoryBandwidthStats { 26 private static final String TAG = "KernelMemoryBandwidthStats"; 27 28 private static final String mSysfsFile = "/sys/kernel/memory_state_time/show_stat"; 29 private static final boolean DEBUG = false; 30 31 protected final LongSparseLongArray mBandwidthEntries = new LongSparseLongArray(); 32 private boolean mStatsDoNotExist = false; 33 updateStats()34 public void updateStats() { 35 if (mStatsDoNotExist) { 36 // Skip reading. 37 return; 38 } 39 40 StrictMode.ThreadPolicy policy = StrictMode.allowThreadDiskReads(); 41 try (BufferedReader reader = new BufferedReader(new FileReader(mSysfsFile))) { 42 parseStats(reader); 43 } catch (FileNotFoundException e) { 44 Slog.w(TAG, "No kernel memory bandwidth stats available"); 45 mBandwidthEntries.clear(); 46 mStatsDoNotExist = true; 47 } catch (IOException e) { 48 Slog.e(TAG, "Failed to read memory bandwidth: " + e.getMessage()); 49 mBandwidthEntries.clear(); 50 } finally { 51 StrictMode.setThreadPolicy(policy); 52 } 53 } 54 55 @VisibleForTesting parseStats(BufferedReader reader)56 public void parseStats(BufferedReader reader) throws IOException { 57 String line; 58 TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter(' '); 59 mBandwidthEntries.clear(); 60 while ((line = reader.readLine()) != null) { 61 splitter.setString(line); 62 splitter.next(); 63 int bandwidth = 0; 64 int index; 65 do { 66 if ((index = mBandwidthEntries.indexOfKey(bandwidth)) >= 0) { 67 mBandwidthEntries.put(bandwidth, mBandwidthEntries.valueAt(index) 68 + Long.parseLong(splitter.next()) / 1000000); 69 } else { 70 mBandwidthEntries.put(bandwidth, Long.parseLong(splitter.next()) / 1000000); 71 } 72 if (DEBUG) { 73 Slog.d(TAG, String.format("bandwidth: %s time: %s", bandwidth, 74 mBandwidthEntries.get(bandwidth))); 75 } 76 bandwidth++; 77 } while(splitter.hasNext()); 78 } 79 } 80 getBandwidthEntries()81 public LongSparseLongArray getBandwidthEntries() { 82 return mBandwidthEntries; 83 } 84 } 85