blob: bf97f1f3e2ed927f404afd3e9e982952e2ff5337 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 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
Dianne Hackborn45ce8642011-07-14 16:10:16 -070017package com.android.internal.os;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
19import static android.os.Process.*;
20
Dianne Hackborn053f61d2013-06-26 18:07:43 -070021import android.os.FileUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import android.os.Process;
Dianne Hackborn8e8d65f2011-08-11 19:36:18 -070023import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import android.os.SystemClock;
Dianne Hackborn62793e42015-03-09 11:15:41 -070025import android.system.OsConstants;
Joe Onorato8a9b2202010-02-26 18:56:32 -080026import android.util.Slog;
Jeff Sharkeyccce0162014-11-07 14:54:55 -080027
Dianne Hackborn8c841092013-06-24 13:46:13 -070028import com.android.internal.util.FastPrintWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029
Jeff Sharkeyccce0162014-11-07 14:54:55 -080030import libcore.io.IoUtils;
Dianne Hackborn62793e42015-03-09 11:15:41 -070031import libcore.io.Libcore;
Jeff Sharkeyccce0162014-11-07 14:54:55 -080032
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033import java.io.File;
34import java.io.FileInputStream;
35import java.io.PrintWriter;
36import java.io.StringWriter;
37import java.util.ArrayList;
38import java.util.Collections;
39import java.util.Comparator;
Amith Yamasanie43530a2009-08-21 13:11:37 -070040import java.util.StringTokenizer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041
Dianne Hackbornd2932242013-08-05 18:18:42 -070042public class ProcessCpuTracker {
Dianne Hackbornae36b232013-09-03 18:12:53 -070043 private static final String TAG = "ProcessCpuTracker";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044 private static final boolean DEBUG = false;
Joe Onorato43a17652011-04-06 19:22:23 -070045 private static final boolean localLOGV = DEBUG || false;
Dianne Hackbornd2932242013-08-05 18:18:42 -070046
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047 private static final int[] PROCESS_STATS_FORMAT = new int[] {
48 PROC_SPACE_TERM,
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -070049 PROC_SPACE_TERM|PROC_PARENS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050 PROC_SPACE_TERM,
51 PROC_SPACE_TERM,
52 PROC_SPACE_TERM,
53 PROC_SPACE_TERM,
54 PROC_SPACE_TERM,
55 PROC_SPACE_TERM,
56 PROC_SPACE_TERM,
Dianne Hackborn8e692572013-09-10 19:06:15 -070057 PROC_SPACE_TERM|PROC_OUT_LONG, // 10: minor faults
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058 PROC_SPACE_TERM,
Dianne Hackborn8e692572013-09-10 19:06:15 -070059 PROC_SPACE_TERM|PROC_OUT_LONG, // 12: major faults
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060 PROC_SPACE_TERM,
Dianne Hackborn8e692572013-09-10 19:06:15 -070061 PROC_SPACE_TERM|PROC_OUT_LONG, // 14: utime
62 PROC_SPACE_TERM|PROC_OUT_LONG, // 15: stime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063 };
64
Dianne Hackborn151ceb92009-08-06 12:40:56 -070065 static final int PROCESS_STAT_MINOR_FAULTS = 0;
66 static final int PROCESS_STAT_MAJOR_FAULTS = 1;
67 static final int PROCESS_STAT_UTIME = 2;
68 static final int PROCESS_STAT_STIME = 3;
Dianne Hackbornd2932242013-08-05 18:18:42 -070069
Amith Yamasanieaeb6632009-06-03 15:16:10 -070070 /** Stores user time and system time in 100ths of a second. */
Dianne Hackborn151ceb92009-08-06 12:40:56 -070071 private final long[] mProcessStatsData = new long[4];
Dianne Hackborn652973f2014-09-10 17:08:48 -070072
73 /** Stores user time and system time in 100ths of a second. Used for
74 * public API to retrieve CPU use for a process. Must lock while in use. */
Dianne Hackborn151ceb92009-08-06 12:40:56 -070075 private final long[] mSinglePidStatsData = new long[4];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076
77 private static final int[] PROCESS_FULL_STATS_FORMAT = new int[] {
78 PROC_SPACE_TERM,
Dianne Hackborn8e692572013-09-10 19:06:15 -070079 PROC_SPACE_TERM|PROC_PARENS|PROC_OUT_STRING, // 2: name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080 PROC_SPACE_TERM,
81 PROC_SPACE_TERM,
82 PROC_SPACE_TERM,
83 PROC_SPACE_TERM,
84 PROC_SPACE_TERM,
85 PROC_SPACE_TERM,
86 PROC_SPACE_TERM,
Dianne Hackborn8e692572013-09-10 19:06:15 -070087 PROC_SPACE_TERM|PROC_OUT_LONG, // 10: minor faults
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088 PROC_SPACE_TERM,
Dianne Hackborn8e692572013-09-10 19:06:15 -070089 PROC_SPACE_TERM|PROC_OUT_LONG, // 12: major faults
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090 PROC_SPACE_TERM,
Dianne Hackborn8e692572013-09-10 19:06:15 -070091 PROC_SPACE_TERM|PROC_OUT_LONG, // 14: utime
92 PROC_SPACE_TERM|PROC_OUT_LONG, // 15: stime
Dianne Hackborn287952c2010-09-22 22:34:31 -070093 PROC_SPACE_TERM,
94 PROC_SPACE_TERM,
95 PROC_SPACE_TERM,
96 PROC_SPACE_TERM,
97 PROC_SPACE_TERM,
98 PROC_SPACE_TERM,
Dianne Hackborn8e692572013-09-10 19:06:15 -070099 PROC_SPACE_TERM,
100 PROC_SPACE_TERM|PROC_OUT_LONG, // 23: vsize
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101 };
102
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700103 static final int PROCESS_FULL_STAT_MINOR_FAULTS = 1;
104 static final int PROCESS_FULL_STAT_MAJOR_FAULTS = 2;
105 static final int PROCESS_FULL_STAT_UTIME = 3;
106 static final int PROCESS_FULL_STAT_STIME = 4;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700107 static final int PROCESS_FULL_STAT_VSIZE = 5;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700108
Dianne Hackborn287952c2010-09-22 22:34:31 -0700109 private final String[] mProcessFullStatsStringData = new String[6];
110 private final long[] mProcessFullStatsData = new long[6];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111
112 private static final int[] SYSTEM_CPU_FORMAT = new int[] {
113 PROC_SPACE_TERM|PROC_COMBINE,
114 PROC_SPACE_TERM|PROC_OUT_LONG, // 1: user time
115 PROC_SPACE_TERM|PROC_OUT_LONG, // 2: nice time
116 PROC_SPACE_TERM|PROC_OUT_LONG, // 3: sys time
117 PROC_SPACE_TERM|PROC_OUT_LONG, // 4: idle time
118 PROC_SPACE_TERM|PROC_OUT_LONG, // 5: iowait time
119 PROC_SPACE_TERM|PROC_OUT_LONG, // 6: irq time
120 PROC_SPACE_TERM|PROC_OUT_LONG // 7: softirq time
121 };
122
123 private final long[] mSystemCpuData = new long[7];
124
125 private static final int[] LOAD_AVERAGE_FORMAT = new int[] {
126 PROC_SPACE_TERM|PROC_OUT_FLOAT, // 0: 1 min
127 PROC_SPACE_TERM|PROC_OUT_FLOAT, // 1: 5 mins
128 PROC_SPACE_TERM|PROC_OUT_FLOAT // 2: 15 mins
129 };
130
131 private final float[] mLoadAverageData = new float[3];
132
133 private final boolean mIncludeThreads;
Dianne Hackbornd2932242013-08-05 18:18:42 -0700134
Dianne Hackborn62793e42015-03-09 11:15:41 -0700135 // How long a CPU jiffy is in milliseconds.
136 private final long mJiffyMillis;
137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138 private float mLoad1 = 0;
139 private float mLoad5 = 0;
140 private float mLoad15 = 0;
Dianne Hackbornd2932242013-08-05 18:18:42 -0700141
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700142 // All times are in milliseconds. They are converted from jiffies to milliseconds
143 // when extracted from the kernel.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144 private long mCurrentSampleTime;
145 private long mLastSampleTime;
Dianne Hackbornd2932242013-08-05 18:18:42 -0700146
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700147 private long mCurrentSampleRealTime;
148 private long mLastSampleRealTime;
149
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 private long mBaseUserTime;
151 private long mBaseSystemTime;
152 private long mBaseIoWaitTime;
153 private long mBaseIrqTime;
154 private long mBaseSoftIrqTime;
155 private long mBaseIdleTime;
156 private int mRelUserTime;
157 private int mRelSystemTime;
158 private int mRelIoWaitTime;
159 private int mRelIrqTime;
160 private int mRelSoftIrqTime;
161 private int mRelIdleTime;
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800162 private boolean mRelStatsAreGood;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163
164 private int[] mCurPids;
165 private int[] mCurThreadPids;
Dianne Hackbornd2932242013-08-05 18:18:42 -0700166
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800167 private final ArrayList<Stats> mProcStats = new ArrayList<Stats>();
168 private final ArrayList<Stats> mWorkingProcs = new ArrayList<Stats>();
169 private boolean mWorkingProcsSorted;
170
171 private boolean mFirst = true;
172
Martin Wallgrenca894b32011-09-20 13:45:48 +0200173 private byte[] mBuffer = new byte[4096];
Amith Yamasanie43530a2009-08-21 13:11:37 -0700174
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800175 public static class Stats {
176 public final int pid;
Dianne Hackborn053f61d2013-06-26 18:07:43 -0700177 public final int uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800178 final String statFile;
179 final String cmdlineFile;
180 final String threadsDir;
181 final ArrayList<Stats> threadStats;
182 final ArrayList<Stats> workingThreads;
Dianne Hackborn053f61d2013-06-26 18:07:43 -0700183
184 public BatteryStatsImpl.Uid.Proc batteryStats;
185
Dianne Hackborn287952c2010-09-22 22:34:31 -0700186 public boolean interesting;
187
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188 public String baseName;
189 public String name;
Dianne Hackborn45ce8642011-07-14 16:10:16 -0700190 public int nameWidth;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800191
Dianne Hackborn8e692572013-09-10 19:06:15 -0700192 // vsize capture when process first detected; can be used to
193 // filter out kernel processes.
194 public long vsize;
195
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700196 /**
197 * Time in milliseconds.
198 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700199 public long base_uptime;
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700200
201 /**
202 * Time in milliseconds.
203 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700204 public long rel_uptime;
205
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700206 /**
207 * Time in milliseconds.
208 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 public long base_utime;
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700210
211 /**
212 * Time in milliseconds.
213 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800214 public long base_stime;
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700215
216 /**
217 * Time in milliseconds.
218 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800219 public int rel_utime;
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700220
221 /**
222 * Time in milliseconds.
223 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224 public int rel_stime;
225
Dianne Hackborn151ceb92009-08-06 12:40:56 -0700226 public long base_minfaults;
227 public long base_majfaults;
228 public int rel_minfaults;
229 public int rel_majfaults;
Dianne Hackbornd2932242013-08-05 18:18:42 -0700230
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231 public boolean active;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700232 public boolean working;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800233 public boolean added;
234 public boolean removed;
Dianne Hackbornd2932242013-08-05 18:18:42 -0700235
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800236 Stats(int _pid, int parentPid, boolean includeThreads) {
237 pid = _pid;
238 if (parentPid < 0) {
239 final File procDir = new File("/proc", Integer.toString(pid));
240 statFile = new File(procDir, "stat").toString();
241 cmdlineFile = new File(procDir, "cmdline").toString();
242 threadsDir = (new File(procDir, "task")).toString();
243 if (includeThreads) {
244 threadStats = new ArrayList<Stats>();
245 workingThreads = new ArrayList<Stats>();
246 } else {
247 threadStats = null;
248 workingThreads = null;
249 }
250 } else {
251 final File procDir = new File("/proc", Integer.toString(
252 parentPid));
253 final File taskDir = new File(
254 new File(procDir, "task"), Integer.toString(pid));
255 statFile = new File(taskDir, "stat").toString();
256 cmdlineFile = null;
257 threadsDir = null;
258 threadStats = null;
259 workingThreads = null;
260 }
Dianne Hackborn053f61d2013-06-26 18:07:43 -0700261 uid = FileUtils.getUid(statFile.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800262 }
263 }
264
265 private final static Comparator<Stats> sLoadComparator = new Comparator<Stats>() {
266 public final int
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700267 compare(Stats sta, Stats stb) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268 int ta = sta.rel_utime + sta.rel_stime;
269 int tb = stb.rel_utime + stb.rel_stime;
270 if (ta != tb) {
271 return ta > tb ? -1 : 1;
272 }
273 if (sta.added != stb.added) {
274 return sta.added ? -1 : 1;
275 }
276 if (sta.removed != stb.removed) {
277 return sta.added ? -1 : 1;
278 }
279 return 0;
280 }
281 };
282
283
Dianne Hackbornd2932242013-08-05 18:18:42 -0700284 public ProcessCpuTracker(boolean includeThreads) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800285 mIncludeThreads = includeThreads;
Dianne Hackborn62793e42015-03-09 11:15:41 -0700286 long jiffyHz = Libcore.os.sysconf(OsConstants._SC_CLK_TCK);
287 mJiffyMillis = 1000/jiffyHz;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800288 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800290 public void onLoadChanged(float load1, float load5, float load15) {
291 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700292
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800293 public int onMeasureProcessName(String name) {
294 return 0;
295 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700296
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800297 public void init() {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700298 if (DEBUG) Slog.v(TAG, "Init: " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800299 mFirst = true;
300 update();
301 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700302
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800303 public void update() {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700304 if (DEBUG) Slog.v(TAG, "Update: " + this);
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800305
306 final long nowUptime = SystemClock.uptimeMillis();
307 final long nowRealtime = SystemClock.elapsedRealtime();
Dianne Hackbornd2932242013-08-05 18:18:42 -0700308
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309 final long[] sysCpu = mSystemCpuData;
310 if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT,
311 null, sysCpu, null)) {
312 // Total user time is user + nice time.
Dianne Hackborn62793e42015-03-09 11:15:41 -0700313 final long usertime = (sysCpu[0]+sysCpu[1]) * mJiffyMillis;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800314 // Total system time is simply system time.
Dianne Hackborn62793e42015-03-09 11:15:41 -0700315 final long systemtime = sysCpu[2] * mJiffyMillis;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800316 // Total idle time is simply idle time.
Dianne Hackborn62793e42015-03-09 11:15:41 -0700317 final long idletime = sysCpu[3] * mJiffyMillis;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800318 // Total irq time is iowait + irq + softirq time.
Dianne Hackborn62793e42015-03-09 11:15:41 -0700319 final long iowaittime = sysCpu[4] * mJiffyMillis;
320 final long irqtime = sysCpu[5] * mJiffyMillis;
321 final long softirqtime = sysCpu[6] * mJiffyMillis;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800323 // This code is trying to avoid issues with idle time going backwards,
324 // but currently it gets into situations where it triggers most of the time. :(
325 if (true || (usertime >= mBaseUserTime && systemtime >= mBaseSystemTime
326 && iowaittime >= mBaseIoWaitTime && irqtime >= mBaseIrqTime
327 && softirqtime >= mBaseSoftIrqTime && idletime >= mBaseIdleTime)) {
328 mRelUserTime = (int)(usertime - mBaseUserTime);
329 mRelSystemTime = (int)(systemtime - mBaseSystemTime);
330 mRelIoWaitTime = (int)(iowaittime - mBaseIoWaitTime);
331 mRelIrqTime = (int)(irqtime - mBaseIrqTime);
332 mRelSoftIrqTime = (int)(softirqtime - mBaseSoftIrqTime);
333 mRelIdleTime = (int)(idletime - mBaseIdleTime);
334 mRelStatsAreGood = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800336 if (DEBUG) {
Dianne Hackborn62793e42015-03-09 11:15:41 -0700337 Slog.i("Load", "Total U:" + (sysCpu[0]*mJiffyMillis)
338 + " N:" + (sysCpu[1]*mJiffyMillis)
339 + " S:" + (sysCpu[2]*mJiffyMillis) + " I:" + (sysCpu[3]*mJiffyMillis)
340 + " W:" + (sysCpu[4]*mJiffyMillis) + " Q:" + (sysCpu[5]*mJiffyMillis)
341 + " O:" + (sysCpu[6]*mJiffyMillis));
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800342 Slog.i("Load", "Rel U:" + mRelUserTime + " S:" + mRelSystemTime
343 + " I:" + mRelIdleTime + " Q:" + mRelIrqTime);
344 }
345
346 mBaseUserTime = usertime;
347 mBaseSystemTime = systemtime;
348 mBaseIoWaitTime = iowaittime;
349 mBaseIrqTime = irqtime;
350 mBaseSoftIrqTime = softirqtime;
351 mBaseIdleTime = idletime;
352
353 } else {
354 mRelUserTime = 0;
355 mRelSystemTime = 0;
356 mRelIoWaitTime = 0;
357 mRelIrqTime = 0;
358 mRelSoftIrqTime = 0;
359 mRelIdleTime = 0;
360 mRelStatsAreGood = false;
361 Slog.w(TAG, "/proc/stats has gone backwards; skipping CPU update");
362 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800364 }
365
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800366 mLastSampleTime = mCurrentSampleTime;
367 mCurrentSampleTime = nowUptime;
368 mLastSampleRealTime = mCurrentSampleRealTime;
369 mCurrentSampleRealTime = nowRealtime;
370
Jeff Sharkeyccce0162014-11-07 14:54:55 -0800371 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
372 try {
373 mCurPids = collectStats("/proc", -1, mFirst, mCurPids, mProcStats);
374 } finally {
375 StrictMode.setThreadPolicy(savedPolicy);
376 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700377
378 final float[] loadAverages = mLoadAverageData;
379 if (Process.readProcFile("/proc/loadavg", LOAD_AVERAGE_FORMAT,
380 null, null, loadAverages)) {
381 float load1 = loadAverages[0];
382 float load5 = loadAverages[1];
383 float load15 = loadAverages[2];
384 if (load1 != mLoad1 || load5 != mLoad5 || load15 != mLoad15) {
385 mLoad1 = load1;
386 mLoad5 = load5;
387 mLoad15 = load15;
388 onLoadChanged(load1, load5, load15);
389 }
390 }
391
392 if (DEBUG) Slog.i(TAG, "*** TIME TO COLLECT STATS: "
393 + (SystemClock.uptimeMillis()-mCurrentSampleTime));
394
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 mWorkingProcsSorted = false;
396 mFirst = false;
Dianne Hackbornd2932242013-08-05 18:18:42 -0700397 }
398
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399 private int[] collectStats(String statsFile, int parentPid, boolean first,
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700400 int[] curPids, ArrayList<Stats> allProcs) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402 int[] pids = Process.getPids(statsFile, curPids);
403 int NP = (pids == null) ? 0 : pids.length;
404 int NS = allProcs.size();
405 int curStatsIndex = 0;
406 for (int i=0; i<NP; i++) {
407 int pid = pids[i];
408 if (pid < 0) {
409 NP = pid;
410 break;
411 }
412 Stats st = curStatsIndex < NS ? allProcs.get(curStatsIndex) : null;
Dianne Hackbornd2932242013-08-05 18:18:42 -0700413
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800414 if (st != null && st.pid == pid) {
415 // Update an existing process...
416 st.added = false;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700417 st.working = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800418 curStatsIndex++;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700419 if (DEBUG) Slog.v(TAG, "Existing "
420 + (parentPid < 0 ? "process" : "thread")
421 + " pid " + pid + ": " + st);
422
Dianne Hackborn287952c2010-09-22 22:34:31 -0700423 if (st.interesting) {
424 final long uptime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800425
Dianne Hackborn287952c2010-09-22 22:34:31 -0700426 final long[] procStats = mProcessStatsData;
427 if (!Process.readProcFile(st.statFile.toString(),
428 PROCESS_STATS_FORMAT, null, procStats, null)) {
429 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800430 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700431
Dianne Hackborn287952c2010-09-22 22:34:31 -0700432 final long minfaults = procStats[PROCESS_STAT_MINOR_FAULTS];
433 final long majfaults = procStats[PROCESS_STAT_MAJOR_FAULTS];
Dianne Hackborn62793e42015-03-09 11:15:41 -0700434 final long utime = procStats[PROCESS_STAT_UTIME] * mJiffyMillis;
435 final long stime = procStats[PROCESS_STAT_STIME] * mJiffyMillis;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800436
Dianne Hackborn287952c2010-09-22 22:34:31 -0700437 if (utime == st.base_utime && stime == st.base_stime) {
438 st.rel_utime = 0;
439 st.rel_stime = 0;
440 st.rel_minfaults = 0;
441 st.rel_majfaults = 0;
442 if (st.active) {
443 st.active = false;
444 }
445 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800446 }
Dianne Hackborn287952c2010-09-22 22:34:31 -0700447
448 if (!st.active) {
449 st.active = true;
450 }
451
452 if (parentPid < 0) {
453 getName(st, st.cmdlineFile);
454 if (st.threadStats != null) {
455 mCurThreadPids = collectStats(st.threadsDir, pid, false,
456 mCurThreadPids, st.threadStats);
457 }
458 }
459
460 if (DEBUG) Slog.v("Load", "Stats changed " + st.name + " pid=" + st.pid
461 + " utime=" + utime + "-" + st.base_utime
462 + " stime=" + stime + "-" + st.base_stime
463 + " minfaults=" + minfaults + "-" + st.base_minfaults
464 + " majfaults=" + majfaults + "-" + st.base_majfaults);
465
466 st.rel_uptime = uptime - st.base_uptime;
467 st.base_uptime = uptime;
468 st.rel_utime = (int)(utime - st.base_utime);
469 st.rel_stime = (int)(stime - st.base_stime);
470 st.base_utime = utime;
471 st.base_stime = stime;
472 st.rel_minfaults = (int)(minfaults - st.base_minfaults);
473 st.rel_majfaults = (int)(majfaults - st.base_majfaults);
474 st.base_minfaults = minfaults;
475 st.base_majfaults = majfaults;
476 st.working = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800477 }
478
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800479 continue;
480 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700481
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800482 if (st == null || st.pid > pid) {
483 // We have a new process!
484 st = new Stats(pid, parentPid, mIncludeThreads);
485 allProcs.add(curStatsIndex, st);
486 curStatsIndex++;
487 NS++;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700488 if (DEBUG) Slog.v(TAG, "New "
489 + (parentPid < 0 ? "process" : "thread")
490 + " pid " + pid + ": " + st);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800491
492 final String[] procStatsString = mProcessFullStatsStringData;
493 final long[] procStats = mProcessFullStatsData;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700494 st.base_uptime = SystemClock.uptimeMillis();
Dianne Hackborn306af672014-06-24 15:41:03 -0700495 String path = st.statFile.toString();
496 //Slog.d(TAG, "Reading proc file: " + path);
497 if (Process.readProcFile(path, PROCESS_FULL_STATS_FORMAT, procStatsString,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800498 procStats, null)) {
Dianne Hackborn287952c2010-09-22 22:34:31 -0700499 // This is a possible way to filter out processes that
500 // are actually kernel threads... do we want to? Some
501 // of them do use CPU, but there can be a *lot* that are
502 // not doing anything.
Dianne Hackborn8e692572013-09-10 19:06:15 -0700503 st.vsize = procStats[PROCESS_FULL_STAT_VSIZE];
Dianne Hackborn287952c2010-09-22 22:34:31 -0700504 if (true || procStats[PROCESS_FULL_STAT_VSIZE] != 0) {
505 st.interesting = true;
506 st.baseName = procStatsString[0];
507 st.base_minfaults = procStats[PROCESS_FULL_STAT_MINOR_FAULTS];
508 st.base_majfaults = procStats[PROCESS_FULL_STAT_MAJOR_FAULTS];
Dianne Hackborn62793e42015-03-09 11:15:41 -0700509 st.base_utime = procStats[PROCESS_FULL_STAT_UTIME] * mJiffyMillis;
510 st.base_stime = procStats[PROCESS_FULL_STAT_STIME] * mJiffyMillis;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700511 } else {
512 Slog.i(TAG, "Skipping kernel process pid " + pid
513 + " name " + procStatsString[0]);
514 st.baseName = procStatsString[0];
515 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800516 } else {
Dianne Hackborn287952c2010-09-22 22:34:31 -0700517 Slog.w(TAG, "Skipping unknown process pid " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800518 st.baseName = "<unknown>";
519 st.base_utime = st.base_stime = 0;
Dianne Hackborn151ceb92009-08-06 12:40:56 -0700520 st.base_minfaults = st.base_majfaults = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800521 }
522
523 if (parentPid < 0) {
524 getName(st, st.cmdlineFile);
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700525 if (st.threadStats != null) {
526 mCurThreadPids = collectStats(st.threadsDir, pid, true,
527 mCurThreadPids, st.threadStats);
528 }
Dianne Hackborn287952c2010-09-22 22:34:31 -0700529 } else if (st.interesting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800530 st.name = st.baseName;
531 st.nameWidth = onMeasureProcessName(st.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800532 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700533
534 if (DEBUG) Slog.v("Load", "Stats added " + st.name + " pid=" + st.pid
535 + " utime=" + st.base_utime + " stime=" + st.base_stime
536 + " minfaults=" + st.base_minfaults + " majfaults=" + st.base_majfaults);
Dianne Hackbornd2932242013-08-05 18:18:42 -0700537
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800538 st.rel_utime = 0;
539 st.rel_stime = 0;
Dianne Hackborn151ceb92009-08-06 12:40:56 -0700540 st.rel_minfaults = 0;
541 st.rel_majfaults = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800542 st.added = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700543 if (!first && st.interesting) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700544 st.working = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800545 }
546 continue;
547 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700548
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549 // This process has gone away!
550 st.rel_utime = 0;
551 st.rel_stime = 0;
Dianne Hackborn151ceb92009-08-06 12:40:56 -0700552 st.rel_minfaults = 0;
553 st.rel_majfaults = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800554 st.removed = true;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700555 st.working = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800556 allProcs.remove(curStatsIndex);
557 NS--;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700558 if (DEBUG) Slog.v(TAG, "Removed "
559 + (parentPid < 0 ? "process" : "thread")
560 + " pid " + pid + ": " + st);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800561 // Decrement the loop counter so that we process the current pid
562 // again the next time through the loop.
563 i--;
564 continue;
565 }
566
567 while (curStatsIndex < NS) {
568 // This process has gone away!
569 final Stats st = allProcs.get(curStatsIndex);
570 st.rel_utime = 0;
571 st.rel_stime = 0;
Dianne Hackborn151ceb92009-08-06 12:40:56 -0700572 st.rel_minfaults = 0;
573 st.rel_majfaults = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800574 st.removed = true;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700575 st.working = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800576 allProcs.remove(curStatsIndex);
577 NS--;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800578 if (localLOGV) Slog.v(TAG, "Removed pid " + st.pid + ": " + st);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800579 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800581 return pids;
582 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700583
Jeff Sharkey3e013e82013-04-25 14:48:19 -0700584 /**
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700585 * Returns the total time (in milliseconds) spent executing in
Dianne Hackborn652973f2014-09-10 17:08:48 -0700586 * both user and system code. Safe to call without lock held.
Jeff Sharkey3e013e82013-04-25 14:48:19 -0700587 */
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700588 public long getCpuTimeForPid(int pid) {
Dianne Hackborn652973f2014-09-10 17:08:48 -0700589 synchronized (mSinglePidStatsData) {
590 final String statFile = "/proc/" + pid + "/stat";
591 final long[] statsData = mSinglePidStatsData;
592 if (Process.readProcFile(statFile, PROCESS_STATS_FORMAT,
593 null, statsData, null)) {
594 long time = statsData[PROCESS_STAT_UTIME]
595 + statsData[PROCESS_STAT_STIME];
Dianne Hackborn62793e42015-03-09 11:15:41 -0700596 return time * mJiffyMillis;
Dianne Hackborn652973f2014-09-10 17:08:48 -0700597 }
598 return 0;
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700599 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700600 }
601
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700602 /**
603 * @return time in milliseconds.
604 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800605 final public int getLastUserTime() {
606 return mRelUserTime;
607 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700608
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700609 /**
610 * @return time in milliseconds.
611 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800612 final public int getLastSystemTime() {
613 return mRelSystemTime;
614 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700615
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700616 /**
617 * @return time in milliseconds.
618 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800619 final public int getLastIoWaitTime() {
620 return mRelIoWaitTime;
621 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700622
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700623 /**
624 * @return time in milliseconds.
625 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800626 final public int getLastIrqTime() {
627 return mRelIrqTime;
628 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700629
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700630 /**
631 * @return time in milliseconds.
632 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800633 final public int getLastSoftIrqTime() {
634 return mRelSoftIrqTime;
635 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700636
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700637 /**
638 * @return time in milliseconds.
639 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800640 final public int getLastIdleTime() {
641 return mRelIdleTime;
642 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700643
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800644 final public boolean hasGoodLastStats() {
645 return mRelStatsAreGood;
646 }
647
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800648 final public float getTotalCpuPercent() {
Dianne Hackborncdadee62012-06-06 11:48:46 -0700649 int denom = mRelUserTime+mRelSystemTime+mRelIrqTime+mRelIdleTime;
650 if (denom <= 0) {
651 return 0;
652 }
653 return ((float)(mRelUserTime+mRelSystemTime+mRelIrqTime)*100) / denom;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800654 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700655
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700656 final void buildWorkingProcs() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800657 if (!mWorkingProcsSorted) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700658 mWorkingProcs.clear();
659 final int N = mProcStats.size();
660 for (int i=0; i<N; i++) {
661 Stats stats = mProcStats.get(i);
662 if (stats.working) {
663 mWorkingProcs.add(stats);
664 if (stats.threadStats != null && stats.threadStats.size() > 1) {
665 stats.workingThreads.clear();
666 final int M = stats.threadStats.size();
667 for (int j=0; j<M; j++) {
668 Stats tstats = stats.threadStats.get(j);
669 if (tstats.working) {
670 stats.workingThreads.add(tstats);
671 }
672 }
673 Collections.sort(stats.workingThreads, sLoadComparator);
674 }
675 }
676 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800677 Collections.sort(mWorkingProcs, sLoadComparator);
678 mWorkingProcsSorted = true;
679 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700680 }
681
Dianne Hackborn287952c2010-09-22 22:34:31 -0700682 final public int countStats() {
683 return mProcStats.size();
684 }
685
686 final public Stats getStats(int index) {
687 return mProcStats.get(index);
688 }
689
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700690 final public int countWorkingStats() {
691 buildWorkingProcs();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800692 return mWorkingProcs.size();
693 }
694
695 final public Stats getWorkingStats(int index) {
696 return mWorkingProcs.get(index);
697 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700698
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700699 final public String printCurrentLoad() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800700 StringWriter sw = new StringWriter();
Dianne Hackborn8c841092013-06-24 13:46:13 -0700701 PrintWriter pw = new FastPrintWriter(sw, false, 128);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800702 pw.print("Load: ");
703 pw.print(mLoad1);
704 pw.print(" / ");
705 pw.print(mLoad5);
706 pw.print(" / ");
707 pw.println(mLoad15);
Dianne Hackborn8c841092013-06-24 13:46:13 -0700708 pw.flush();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700709 return sw.toString();
710 }
711
712 final public String printCurrentState(long now) {
713 buildWorkingProcs();
Dianne Hackbornd2932242013-08-05 18:18:42 -0700714
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700715 StringWriter sw = new StringWriter();
Dianne Hackborn8c841092013-06-24 13:46:13 -0700716 PrintWriter pw = new FastPrintWriter(sw, false, 1024);
Dianne Hackbornd2932242013-08-05 18:18:42 -0700717
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800718 pw.print("CPU usage from ");
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700719 if (now > mLastSampleTime) {
720 pw.print(now-mLastSampleTime);
721 pw.print("ms to ");
722 pw.print(now-mCurrentSampleTime);
723 pw.print("ms ago");
724 } else {
725 pw.print(mLastSampleTime-now);
726 pw.print("ms to ");
727 pw.print(mCurrentSampleTime-now);
728 pw.print("ms later");
729 }
730
731 long sampleTime = mCurrentSampleTime - mLastSampleTime;
732 long sampleRealTime = mCurrentSampleRealTime - mLastSampleRealTime;
Dianne Hackborncdadee62012-06-06 11:48:46 -0700733 long percAwake = sampleRealTime > 0 ? ((sampleTime*100) / sampleRealTime) : 0;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700734 if (percAwake != 100) {
735 pw.print(" with ");
736 pw.print(percAwake);
737 pw.print("% awake");
738 }
739 pw.println(":");
Dianne Hackbornd2932242013-08-05 18:18:42 -0700740
Dianne Hackborn151ceb92009-08-06 12:40:56 -0700741 final int totalTime = mRelUserTime + mRelSystemTime + mRelIoWaitTime
742 + mRelIrqTime + mRelSoftIrqTime + mRelIdleTime;
Dianne Hackbornd2932242013-08-05 18:18:42 -0700743
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700744 if (DEBUG) Slog.i(TAG, "totalTime " + totalTime + " over sample time "
745 + (mCurrentSampleTime-mLastSampleTime));
746
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800747 int N = mWorkingProcs.size();
748 for (int i=0; i<N; i++) {
749 Stats st = mWorkingProcs.get(i);
750 printProcessCPU(pw, st.added ? " +" : (st.removed ? " -": " "),
Dianne Hackborn62793e42015-03-09 11:15:41 -0700751 st.pid, st.name, (int)st.rel_uptime,
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700752 st.rel_utime, st.rel_stime, 0, 0, 0, st.rel_minfaults, st.rel_majfaults);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800753 if (!st.removed && st.workingThreads != null) {
754 int M = st.workingThreads.size();
755 for (int j=0; j<M; j++) {
756 Stats tst = st.workingThreads.get(j);
757 printProcessCPU(pw,
758 tst.added ? " +" : (tst.removed ? " -": " "),
Dianne Hackborn62793e42015-03-09 11:15:41 -0700759 tst.pid, tst.name, (int)st.rel_uptime,
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700760 tst.rel_utime, tst.rel_stime, 0, 0, 0, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800761 }
762 }
763 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700764
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700765 printProcessCPU(pw, "", -1, "TOTAL", totalTime, mRelUserTime, mRelSystemTime,
Dianne Hackborn151ceb92009-08-06 12:40:56 -0700766 mRelIoWaitTime, mRelIrqTime, mRelSoftIrqTime, 0, 0);
Dianne Hackborn8c841092013-06-24 13:46:13 -0700767
768 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800769 return sw.toString();
770 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700771
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700772 private void printRatio(PrintWriter pw, long numerator, long denominator) {
773 long thousands = (numerator*1000)/denominator;
774 long hundreds = thousands/10;
775 pw.print(hundreds);
776 if (hundreds < 10) {
777 long remainder = thousands - (hundreds*10);
778 if (remainder != 0) {
779 pw.print('.');
780 pw.print(remainder);
781 }
782 }
783 }
784
785 private void printProcessCPU(PrintWriter pw, String prefix, int pid, String label,
786 int totalTime, int user, int system, int iowait, int irq, int softIrq,
787 int minFaults, int majFaults) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800788 pw.print(prefix);
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700789 if (totalTime == 0) totalTime = 1;
790 printRatio(pw, user+system+iowait+irq+softIrq, totalTime);
791 pw.print("% ");
792 if (pid >= 0) {
793 pw.print(pid);
794 pw.print("/");
795 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800796 pw.print(label);
797 pw.print(": ");
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700798 printRatio(pw, user, totalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800799 pw.print("% user + ");
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700800 printRatio(pw, system, totalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800801 pw.print("% kernel");
802 if (iowait > 0) {
803 pw.print(" + ");
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700804 printRatio(pw, iowait, totalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800805 pw.print("% iowait");
806 }
807 if (irq > 0) {
808 pw.print(" + ");
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700809 printRatio(pw, irq, totalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800810 pw.print("% irq");
811 }
812 if (softIrq > 0) {
813 pw.print(" + ");
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700814 printRatio(pw, softIrq, totalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800815 pw.print("% softirq");
816 }
Dianne Hackborn151ceb92009-08-06 12:40:56 -0700817 if (minFaults > 0 || majFaults > 0) {
818 pw.print(" / faults:");
819 if (minFaults > 0) {
820 pw.print(" ");
821 pw.print(minFaults);
822 pw.print(" minor");
823 }
824 if (majFaults > 0) {
825 pw.print(" ");
826 pw.print(majFaults);
827 pw.print(" major");
828 }
829 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800830 pw.println();
831 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700832
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800833 private String readFile(String file, char endChar) {
Dianne Hackborn8e8d65f2011-08-11 19:36:18 -0700834 // Permit disk reads here, as /proc/meminfo isn't really "on
835 // disk" and should be fast. TODO: make BlockGuard ignore
836 // /proc/ and /sys/ files perhaps?
837 StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
Brad Fitzpatrick6689ac82010-11-15 16:26:04 -0800838 FileInputStream is = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800839 try {
Brad Fitzpatrick6689ac82010-11-15 16:26:04 -0800840 is = new FileInputStream(file);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800841 int len = is.read(mBuffer);
842 is.close();
843
844 if (len > 0) {
845 int i;
846 for (i=0; i<len; i++) {
847 if (mBuffer[i] == endChar) {
848 break;
849 }
850 }
Christian Mehlmauer4136c982010-05-25 20:04:09 +0200851 return new String(mBuffer, 0, i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800852 }
853 } catch (java.io.FileNotFoundException e) {
854 } catch (java.io.IOException e) {
Brad Fitzpatrick6689ac82010-11-15 16:26:04 -0800855 } finally {
Jeff Sharkeyccce0162014-11-07 14:54:55 -0800856 IoUtils.closeQuietly(is);
Dianne Hackborn8e8d65f2011-08-11 19:36:18 -0700857 StrictMode.setThreadPolicy(savedPolicy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800858 }
859 return null;
860 }
861
862 private void getName(Stats st, String cmdlineFile) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700863 String newName = st.name;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700864 if (st.name == null || st.name.equals("app_process")
865 || st.name.equals("<pre-initialized>")) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800866 String cmdName = readFile(cmdlineFile, '\0');
867 if (cmdName != null && cmdName.length() > 1) {
868 newName = cmdName;
869 int i = newName.lastIndexOf("/");
870 if (i > 0 && i < newName.length()-1) {
871 newName = newName.substring(i+1);
872 }
873 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700874 if (newName == null) {
875 newName = st.baseName;
876 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800877 }
878 if (st.name == null || !newName.equals(st.name)) {
879 st.name = newName;
880 st.nameWidth = onMeasureProcessName(st.name);
881 }
882 }
883}