/**
* Pulls Cpu time per frequency.
- * Note: this should be pulled for gauge metric only, without condition.
- * The puller keeps internal state of last values. It should not be pulled by
- * different metrics.
- * The pulled data is delta of cpu time from last pull, calculated as
- * following:
- * if current time is larger than last value, take delta between the two.
- * if current time is smaller than last value, there must be a cpu
- * hotplug event, and the current time is taken as delta.
+ * Pulls the time the cpu spend on the frequency index. Frequency index
+ * starts from highest to lowest. The value should be monotonically
+ * increasing since boot. However, if there is a cpu
+ * hotplug event, the value would be reset as well.
*/
message CpuTimePerFreq {
optional uint32 cluster = 1;
private static final String TAG = "KernelCpuSpeedReader";
private final String mProcFile;
+ private final int mNumSpeedSteps;
private final long[] mLastSpeedTimesMs;
private final long[] mDeltaSpeedTimesMs;
public KernelCpuSpeedReader(int cpuNumber, int numSpeedSteps) {
mProcFile = String.format("/sys/devices/system/cpu/cpu%d/cpufreq/stats/time_in_state",
cpuNumber);
+ mNumSpeedSteps = numSpeedSteps;
mLastSpeedTimesMs = new long[numSpeedSteps];
mDeltaSpeedTimesMs = new long[numSpeedSteps];
long jiffyHz = Os.sysconf(OsConstants._SC_CLK_TCK);
}
return mDeltaSpeedTimesMs;
}
+
+ /**
+ * @return The time (in milliseconds) spent at different cpu speeds. The values should be
+ * monotonically increasing, unless the cpu was hotplugged.
+ */
+ public long[] readAbsolute() {
+ StrictMode.ThreadPolicy policy = StrictMode.allowThreadDiskReads();
+ long[] speedTimeMs = new long[mNumSpeedSteps];
+ try (BufferedReader reader = new BufferedReader(new FileReader(mProcFile))) {
+ TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter(' ');
+ String line;
+ int speedIndex = 0;
+ while (speedIndex < mNumSpeedSteps && (line = reader.readLine()) != null) {
+ splitter.setString(line);
+ splitter.next();
+ long time = Long.parseLong(splitter.next()) * mJiffyMillis;
+ speedTimeMs[speedIndex] = time;
+ speedIndex++;
+ }
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to read cpu-freq: " + e.getMessage());
+ Arrays.fill(speedTimeMs, 0);
+ } finally {
+ StrictMode.setThreadPolicy(policy);
+ }
+ return speedTimeMs;
+ }
}
case StatsLog.CPU_TIME_PER_FREQ: {
List<StatsLogEventWrapper> ret = new ArrayList();
for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) {
- long[] clusterTimeMs = mKernelCpuSpeedReaders[cluster].readDelta();
+ long[] clusterTimeMs = mKernelCpuSpeedReaders[cluster].readAbsolute();
if (clusterTimeMs != null) {
for (int speed = clusterTimeMs.length - 1; speed >= 0; --speed) {
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, 3);