1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.internal.os;
17 
18 import android.text.TextUtils;
19 import android.util.Slog;
20 
21 import java.io.BufferedReader;
22 import java.io.FileReader;
23 import java.io.IOException;
24 import java.util.Arrays;
25 
26 /**
27  * Reads CPU time spent at various frequencies and provides a delta from the last call to
28  * {@link #readDelta}. Each line in the proc file has the format:
29  *
30  * freq time
31  *
32  * where time is measured in 1/100 seconds.
33  */
34 public class KernelCpuSpeedReader {
35     private static final String TAG = "KernelCpuSpeedReader";
36     private static final String sProcFile =
37             "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state";
38     private static final int MAX_SPEEDS = 60;
39 
40     private long[] mLastSpeedTimes = new long[MAX_SPEEDS];
41     private long[] mDeltaSpeedTimes = new long[MAX_SPEEDS];
42 
43     /**
44      * The returned array is modified in subsequent calls to {@link #readDelta}.
45      * @return The time (in milliseconds) spent at different cpu speeds since the last call to
46      * {@link #readDelta}.
47      */
readDelta()48     public long[] readDelta() {
49         try (BufferedReader reader = new BufferedReader(new FileReader(sProcFile))) {
50             TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter(' ');
51             String line;
52             int speedIndex = 0;
53             while ((line = reader.readLine()) != null) {
54                 splitter.setString(line);
55                 Long.parseLong(splitter.next());
56 
57                 // The proc file reports time in 1/100 sec, so convert to milliseconds.
58                 long time = Long.parseLong(splitter.next()) * 10;
59                 mDeltaSpeedTimes[speedIndex] = time - mLastSpeedTimes[speedIndex];
60                 mLastSpeedTimes[speedIndex] = time;
61                 speedIndex++;
62             }
63         } catch (IOException e) {
64             Slog.e(TAG, "Failed to read cpu-freq", e);
65             Arrays.fill(mDeltaSpeedTimes, 0);
66         }
67         return mDeltaSpeedTimes;
68     }
69 }
70