blob: e46dfc4e0cb65102193a195141548c20809d23ec [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;
Joe Onoratod2bc2ba2016-04-15 13:34:25 -070037import java.text.SimpleDateFormat;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038import java.util.ArrayList;
39import java.util.Collections;
40import java.util.Comparator;
Joe Onoratod2bc2ba2016-04-15 13:34:25 -070041import java.util.Date;
Amith Yamasani10e8f162016-08-30 16:39:03 -070042import java.util.List;
Amith Yamasanie43530a2009-08-21 13:11:37 -070043import java.util.StringTokenizer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044
Dianne Hackbornd2932242013-08-05 18:18:42 -070045public class ProcessCpuTracker {
Dianne Hackbornae36b232013-09-03 18:12:53 -070046 private static final String TAG = "ProcessCpuTracker";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047 private static final boolean DEBUG = false;
Joe Onorato43a17652011-04-06 19:22:23 -070048 private static final boolean localLOGV = DEBUG || false;
Dianne Hackbornd2932242013-08-05 18:18:42 -070049
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050 private static final int[] PROCESS_STATS_FORMAT = new int[] {
51 PROC_SPACE_TERM,
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -070052 PROC_SPACE_TERM|PROC_PARENS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053 PROC_SPACE_TERM,
54 PROC_SPACE_TERM,
55 PROC_SPACE_TERM,
56 PROC_SPACE_TERM,
57 PROC_SPACE_TERM,
58 PROC_SPACE_TERM,
59 PROC_SPACE_TERM,
Dianne Hackborn8e692572013-09-10 19:06:15 -070060 PROC_SPACE_TERM|PROC_OUT_LONG, // 10: minor faults
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061 PROC_SPACE_TERM,
Dianne Hackborn8e692572013-09-10 19:06:15 -070062 PROC_SPACE_TERM|PROC_OUT_LONG, // 12: major faults
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063 PROC_SPACE_TERM,
Dianne Hackborn8e692572013-09-10 19:06:15 -070064 PROC_SPACE_TERM|PROC_OUT_LONG, // 14: utime
65 PROC_SPACE_TERM|PROC_OUT_LONG, // 15: stime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066 };
67
Dianne Hackborn151ceb92009-08-06 12:40:56 -070068 static final int PROCESS_STAT_MINOR_FAULTS = 0;
69 static final int PROCESS_STAT_MAJOR_FAULTS = 1;
70 static final int PROCESS_STAT_UTIME = 2;
71 static final int PROCESS_STAT_STIME = 3;
Dianne Hackbornd2932242013-08-05 18:18:42 -070072
Thierry Strudelb786aaa2016-01-21 16:31:21 -080073 /** Stores user time and system time in jiffies. */
Dianne Hackborn151ceb92009-08-06 12:40:56 -070074 private final long[] mProcessStatsData = new long[4];
Dianne Hackborn652973f2014-09-10 17:08:48 -070075
Thierry Strudelb786aaa2016-01-21 16:31:21 -080076 /** Stores user time and system time in jiffies. Used for
Dianne Hackborn652973f2014-09-10 17:08:48 -070077 * public API to retrieve CPU use for a process. Must lock while in use. */
Dianne Hackborn151ceb92009-08-06 12:40:56 -070078 private final long[] mSinglePidStatsData = new long[4];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079
80 private static final int[] PROCESS_FULL_STATS_FORMAT = new int[] {
81 PROC_SPACE_TERM,
Dianne Hackborn8e692572013-09-10 19:06:15 -070082 PROC_SPACE_TERM|PROC_PARENS|PROC_OUT_STRING, // 2: name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083 PROC_SPACE_TERM,
84 PROC_SPACE_TERM,
85 PROC_SPACE_TERM,
86 PROC_SPACE_TERM,
87 PROC_SPACE_TERM,
88 PROC_SPACE_TERM,
89 PROC_SPACE_TERM,
Dianne Hackborn8e692572013-09-10 19:06:15 -070090 PROC_SPACE_TERM|PROC_OUT_LONG, // 10: minor faults
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091 PROC_SPACE_TERM,
Dianne Hackborn8e692572013-09-10 19:06:15 -070092 PROC_SPACE_TERM|PROC_OUT_LONG, // 12: major faults
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 PROC_SPACE_TERM,
Dianne Hackborn8e692572013-09-10 19:06:15 -070094 PROC_SPACE_TERM|PROC_OUT_LONG, // 14: utime
95 PROC_SPACE_TERM|PROC_OUT_LONG, // 15: stime
Dianne Hackborn287952c2010-09-22 22:34:31 -070096 PROC_SPACE_TERM,
97 PROC_SPACE_TERM,
98 PROC_SPACE_TERM,
99 PROC_SPACE_TERM,
100 PROC_SPACE_TERM,
101 PROC_SPACE_TERM,
Dianne Hackborn8e692572013-09-10 19:06:15 -0700102 PROC_SPACE_TERM,
103 PROC_SPACE_TERM|PROC_OUT_LONG, // 23: vsize
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104 };
105
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700106 static final int PROCESS_FULL_STAT_MINOR_FAULTS = 1;
107 static final int PROCESS_FULL_STAT_MAJOR_FAULTS = 2;
108 static final int PROCESS_FULL_STAT_UTIME = 3;
109 static final int PROCESS_FULL_STAT_STIME = 4;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700110 static final int PROCESS_FULL_STAT_VSIZE = 5;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700111
Dianne Hackborn287952c2010-09-22 22:34:31 -0700112 private final String[] mProcessFullStatsStringData = new String[6];
113 private final long[] mProcessFullStatsData = new long[6];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114
115 private static final int[] SYSTEM_CPU_FORMAT = new int[] {
116 PROC_SPACE_TERM|PROC_COMBINE,
117 PROC_SPACE_TERM|PROC_OUT_LONG, // 1: user time
118 PROC_SPACE_TERM|PROC_OUT_LONG, // 2: nice time
119 PROC_SPACE_TERM|PROC_OUT_LONG, // 3: sys time
120 PROC_SPACE_TERM|PROC_OUT_LONG, // 4: idle time
121 PROC_SPACE_TERM|PROC_OUT_LONG, // 5: iowait time
122 PROC_SPACE_TERM|PROC_OUT_LONG, // 6: irq time
123 PROC_SPACE_TERM|PROC_OUT_LONG // 7: softirq time
124 };
125
126 private final long[] mSystemCpuData = new long[7];
127
128 private static final int[] LOAD_AVERAGE_FORMAT = new int[] {
129 PROC_SPACE_TERM|PROC_OUT_FLOAT, // 0: 1 min
130 PROC_SPACE_TERM|PROC_OUT_FLOAT, // 1: 5 mins
131 PROC_SPACE_TERM|PROC_OUT_FLOAT // 2: 15 mins
132 };
133
134 private final float[] mLoadAverageData = new float[3];
135
136 private final boolean mIncludeThreads;
Dianne Hackbornd2932242013-08-05 18:18:42 -0700137
Dianne Hackborn62793e42015-03-09 11:15:41 -0700138 // How long a CPU jiffy is in milliseconds.
139 private final long mJiffyMillis;
140
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141 private float mLoad1 = 0;
142 private float mLoad5 = 0;
143 private float mLoad15 = 0;
Dianne Hackbornd2932242013-08-05 18:18:42 -0700144
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700145 // All times are in milliseconds. They are converted from jiffies to milliseconds
146 // when extracted from the kernel.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 private long mCurrentSampleTime;
148 private long mLastSampleTime;
Dianne Hackbornd2932242013-08-05 18:18:42 -0700149
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700150 private long mCurrentSampleRealTime;
151 private long mLastSampleRealTime;
152
Joe Onoratod2bc2ba2016-04-15 13:34:25 -0700153 private long mCurrentSampleWallTime;
154 private long mLastSampleWallTime;
155
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800156 private long mBaseUserTime;
157 private long mBaseSystemTime;
158 private long mBaseIoWaitTime;
159 private long mBaseIrqTime;
160 private long mBaseSoftIrqTime;
161 private long mBaseIdleTime;
162 private int mRelUserTime;
163 private int mRelSystemTime;
164 private int mRelIoWaitTime;
165 private int mRelIrqTime;
166 private int mRelSoftIrqTime;
167 private int mRelIdleTime;
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800168 private boolean mRelStatsAreGood;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169
170 private int[] mCurPids;
171 private int[] mCurThreadPids;
Dianne Hackbornd2932242013-08-05 18:18:42 -0700172
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800173 private final ArrayList<Stats> mProcStats = new ArrayList<Stats>();
174 private final ArrayList<Stats> mWorkingProcs = new ArrayList<Stats>();
175 private boolean mWorkingProcsSorted;
176
177 private boolean mFirst = true;
178
Martin Wallgrenca894b32011-09-20 13:45:48 +0200179 private byte[] mBuffer = new byte[4096];
Amith Yamasanie43530a2009-08-21 13:11:37 -0700180
Amith Yamasani10e8f162016-08-30 16:39:03 -0700181 public interface FilterStats {
182 /** Which stats to pick when filtering */
183 boolean needed(Stats stats);
184 }
185
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186 public static class Stats {
187 public final int pid;
Dianne Hackborn053f61d2013-06-26 18:07:43 -0700188 public final int uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800189 final String statFile;
190 final String cmdlineFile;
191 final String threadsDir;
192 final ArrayList<Stats> threadStats;
193 final ArrayList<Stats> workingThreads;
Dianne Hackborn053f61d2013-06-26 18:07:43 -0700194
195 public BatteryStatsImpl.Uid.Proc batteryStats;
196
Dianne Hackborn287952c2010-09-22 22:34:31 -0700197 public boolean interesting;
198
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800199 public String baseName;
200 public String name;
Dianne Hackborn45ce8642011-07-14 16:10:16 -0700201 public int nameWidth;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202
Dianne Hackborn8e692572013-09-10 19:06:15 -0700203 // vsize capture when process first detected; can be used to
204 // filter out kernel processes.
205 public long vsize;
206
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700207 /**
208 * Time in milliseconds.
209 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700210 public long base_uptime;
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700211
212 /**
213 * Time in milliseconds.
214 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700215 public long rel_uptime;
216
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700217 /**
218 * Time in milliseconds.
219 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220 public long base_utime;
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700221
222 /**
223 * Time in milliseconds.
224 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800225 public long base_stime;
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700226
227 /**
228 * Time in milliseconds.
229 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800230 public int rel_utime;
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700231
232 /**
233 * Time in milliseconds.
234 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800235 public int rel_stime;
236
Dianne Hackborn151ceb92009-08-06 12:40:56 -0700237 public long base_minfaults;
238 public long base_majfaults;
239 public int rel_minfaults;
240 public int rel_majfaults;
Dianne Hackbornd2932242013-08-05 18:18:42 -0700241
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242 public boolean active;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700243 public boolean working;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800244 public boolean added;
245 public boolean removed;
Dianne Hackbornd2932242013-08-05 18:18:42 -0700246
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247 Stats(int _pid, int parentPid, boolean includeThreads) {
248 pid = _pid;
249 if (parentPid < 0) {
250 final File procDir = new File("/proc", Integer.toString(pid));
251 statFile = new File(procDir, "stat").toString();
252 cmdlineFile = new File(procDir, "cmdline").toString();
253 threadsDir = (new File(procDir, "task")).toString();
254 if (includeThreads) {
255 threadStats = new ArrayList<Stats>();
256 workingThreads = new ArrayList<Stats>();
257 } else {
258 threadStats = null;
259 workingThreads = null;
260 }
261 } else {
262 final File procDir = new File("/proc", Integer.toString(
263 parentPid));
264 final File taskDir = new File(
265 new File(procDir, "task"), Integer.toString(pid));
266 statFile = new File(taskDir, "stat").toString();
267 cmdlineFile = null;
268 threadsDir = null;
269 threadStats = null;
270 workingThreads = null;
271 }
Dianne Hackborn053f61d2013-06-26 18:07:43 -0700272 uid = FileUtils.getUid(statFile.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800273 }
274 }
275
276 private final static Comparator<Stats> sLoadComparator = new Comparator<Stats>() {
277 public final int
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700278 compare(Stats sta, Stats stb) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 int ta = sta.rel_utime + sta.rel_stime;
280 int tb = stb.rel_utime + stb.rel_stime;
281 if (ta != tb) {
282 return ta > tb ? -1 : 1;
283 }
284 if (sta.added != stb.added) {
285 return sta.added ? -1 : 1;
286 }
287 if (sta.removed != stb.removed) {
288 return sta.added ? -1 : 1;
289 }
290 return 0;
291 }
292 };
293
294
Dianne Hackbornd2932242013-08-05 18:18:42 -0700295 public ProcessCpuTracker(boolean includeThreads) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800296 mIncludeThreads = includeThreads;
Dianne Hackborn62793e42015-03-09 11:15:41 -0700297 long jiffyHz = Libcore.os.sysconf(OsConstants._SC_CLK_TCK);
298 mJiffyMillis = 1000/jiffyHz;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800299 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700300
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301 public void onLoadChanged(float load1, float load5, float load15) {
302 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700303
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800304 public int onMeasureProcessName(String name) {
305 return 0;
306 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800308 public void init() {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700309 if (DEBUG) Slog.v(TAG, "Init: " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310 mFirst = true;
311 update();
312 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700313
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800314 public void update() {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700315 if (DEBUG) Slog.v(TAG, "Update: " + this);
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800316
317 final long nowUptime = SystemClock.uptimeMillis();
318 final long nowRealtime = SystemClock.elapsedRealtime();
Joe Onoratod2bc2ba2016-04-15 13:34:25 -0700319 final long nowWallTime = System.currentTimeMillis();
Dianne Hackbornd2932242013-08-05 18:18:42 -0700320
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800321 final long[] sysCpu = mSystemCpuData;
322 if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT,
323 null, sysCpu, null)) {
324 // Total user time is user + nice time.
Dianne Hackborn62793e42015-03-09 11:15:41 -0700325 final long usertime = (sysCpu[0]+sysCpu[1]) * mJiffyMillis;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326 // Total system time is simply system time.
Dianne Hackborn62793e42015-03-09 11:15:41 -0700327 final long systemtime = sysCpu[2] * mJiffyMillis;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328 // Total idle time is simply idle time.
Dianne Hackborn62793e42015-03-09 11:15:41 -0700329 final long idletime = sysCpu[3] * mJiffyMillis;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330 // Total irq time is iowait + irq + softirq time.
Dianne Hackborn62793e42015-03-09 11:15:41 -0700331 final long iowaittime = sysCpu[4] * mJiffyMillis;
332 final long irqtime = sysCpu[5] * mJiffyMillis;
333 final long softirqtime = sysCpu[6] * mJiffyMillis;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800334
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800335 // This code is trying to avoid issues with idle time going backwards,
336 // but currently it gets into situations where it triggers most of the time. :(
337 if (true || (usertime >= mBaseUserTime && systemtime >= mBaseSystemTime
338 && iowaittime >= mBaseIoWaitTime && irqtime >= mBaseIrqTime
339 && softirqtime >= mBaseSoftIrqTime && idletime >= mBaseIdleTime)) {
340 mRelUserTime = (int)(usertime - mBaseUserTime);
341 mRelSystemTime = (int)(systemtime - mBaseSystemTime);
342 mRelIoWaitTime = (int)(iowaittime - mBaseIoWaitTime);
343 mRelIrqTime = (int)(irqtime - mBaseIrqTime);
344 mRelSoftIrqTime = (int)(softirqtime - mBaseSoftIrqTime);
345 mRelIdleTime = (int)(idletime - mBaseIdleTime);
346 mRelStatsAreGood = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800347
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800348 if (DEBUG) {
Dianne Hackborn62793e42015-03-09 11:15:41 -0700349 Slog.i("Load", "Total U:" + (sysCpu[0]*mJiffyMillis)
350 + " N:" + (sysCpu[1]*mJiffyMillis)
351 + " S:" + (sysCpu[2]*mJiffyMillis) + " I:" + (sysCpu[3]*mJiffyMillis)
352 + " W:" + (sysCpu[4]*mJiffyMillis) + " Q:" + (sysCpu[5]*mJiffyMillis)
353 + " O:" + (sysCpu[6]*mJiffyMillis));
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800354 Slog.i("Load", "Rel U:" + mRelUserTime + " S:" + mRelSystemTime
355 + " I:" + mRelIdleTime + " Q:" + mRelIrqTime);
356 }
357
358 mBaseUserTime = usertime;
359 mBaseSystemTime = systemtime;
360 mBaseIoWaitTime = iowaittime;
361 mBaseIrqTime = irqtime;
362 mBaseSoftIrqTime = softirqtime;
363 mBaseIdleTime = idletime;
364
365 } else {
366 mRelUserTime = 0;
367 mRelSystemTime = 0;
368 mRelIoWaitTime = 0;
369 mRelIrqTime = 0;
370 mRelSoftIrqTime = 0;
371 mRelIdleTime = 0;
372 mRelStatsAreGood = false;
373 Slog.w(TAG, "/proc/stats has gone backwards; skipping CPU update");
374 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800375 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800376 }
377
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800378 mLastSampleTime = mCurrentSampleTime;
379 mCurrentSampleTime = nowUptime;
380 mLastSampleRealTime = mCurrentSampleRealTime;
381 mCurrentSampleRealTime = nowRealtime;
Joe Onoratod2bc2ba2016-04-15 13:34:25 -0700382 mLastSampleWallTime = mCurrentSampleWallTime;
383 mCurrentSampleWallTime = nowWallTime;
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800384
Jeff Sharkeyccce0162014-11-07 14:54:55 -0800385 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
386 try {
387 mCurPids = collectStats("/proc", -1, mFirst, mCurPids, mProcStats);
388 } finally {
389 StrictMode.setThreadPolicy(savedPolicy);
390 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700391
392 final float[] loadAverages = mLoadAverageData;
393 if (Process.readProcFile("/proc/loadavg", LOAD_AVERAGE_FORMAT,
394 null, null, loadAverages)) {
395 float load1 = loadAverages[0];
396 float load5 = loadAverages[1];
397 float load15 = loadAverages[2];
398 if (load1 != mLoad1 || load5 != mLoad5 || load15 != mLoad15) {
399 mLoad1 = load1;
400 mLoad5 = load5;
401 mLoad15 = load15;
402 onLoadChanged(load1, load5, load15);
403 }
404 }
405
406 if (DEBUG) Slog.i(TAG, "*** TIME TO COLLECT STATS: "
407 + (SystemClock.uptimeMillis()-mCurrentSampleTime));
408
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409 mWorkingProcsSorted = false;
410 mFirst = false;
Dianne Hackbornd2932242013-08-05 18:18:42 -0700411 }
412
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800413 private int[] collectStats(String statsFile, int parentPid, boolean first,
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700414 int[] curPids, ArrayList<Stats> allProcs) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700415
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800416 int[] pids = Process.getPids(statsFile, curPids);
417 int NP = (pids == null) ? 0 : pids.length;
418 int NS = allProcs.size();
419 int curStatsIndex = 0;
420 for (int i=0; i<NP; i++) {
421 int pid = pids[i];
422 if (pid < 0) {
423 NP = pid;
424 break;
425 }
426 Stats st = curStatsIndex < NS ? allProcs.get(curStatsIndex) : null;
Dianne Hackbornd2932242013-08-05 18:18:42 -0700427
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800428 if (st != null && st.pid == pid) {
429 // Update an existing process...
430 st.added = false;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700431 st.working = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800432 curStatsIndex++;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700433 if (DEBUG) Slog.v(TAG, "Existing "
434 + (parentPid < 0 ? "process" : "thread")
435 + " pid " + pid + ": " + st);
436
Dianne Hackborn287952c2010-09-22 22:34:31 -0700437 if (st.interesting) {
438 final long uptime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800439
Dianne Hackborn287952c2010-09-22 22:34:31 -0700440 final long[] procStats = mProcessStatsData;
441 if (!Process.readProcFile(st.statFile.toString(),
442 PROCESS_STATS_FORMAT, null, procStats, null)) {
443 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800444 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700445
Dianne Hackborn287952c2010-09-22 22:34:31 -0700446 final long minfaults = procStats[PROCESS_STAT_MINOR_FAULTS];
447 final long majfaults = procStats[PROCESS_STAT_MAJOR_FAULTS];
Dianne Hackborn62793e42015-03-09 11:15:41 -0700448 final long utime = procStats[PROCESS_STAT_UTIME] * mJiffyMillis;
449 final long stime = procStats[PROCESS_STAT_STIME] * mJiffyMillis;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800450
Dianne Hackborn287952c2010-09-22 22:34:31 -0700451 if (utime == st.base_utime && stime == st.base_stime) {
452 st.rel_utime = 0;
453 st.rel_stime = 0;
454 st.rel_minfaults = 0;
455 st.rel_majfaults = 0;
456 if (st.active) {
457 st.active = false;
458 }
459 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800460 }
Dianne Hackborn287952c2010-09-22 22:34:31 -0700461
462 if (!st.active) {
463 st.active = true;
464 }
465
466 if (parentPid < 0) {
467 getName(st, st.cmdlineFile);
468 if (st.threadStats != null) {
469 mCurThreadPids = collectStats(st.threadsDir, pid, false,
470 mCurThreadPids, st.threadStats);
471 }
472 }
473
474 if (DEBUG) Slog.v("Load", "Stats changed " + st.name + " pid=" + st.pid
475 + " utime=" + utime + "-" + st.base_utime
476 + " stime=" + stime + "-" + st.base_stime
477 + " minfaults=" + minfaults + "-" + st.base_minfaults
478 + " majfaults=" + majfaults + "-" + st.base_majfaults);
479
480 st.rel_uptime = uptime - st.base_uptime;
481 st.base_uptime = uptime;
482 st.rel_utime = (int)(utime - st.base_utime);
483 st.rel_stime = (int)(stime - st.base_stime);
484 st.base_utime = utime;
485 st.base_stime = stime;
486 st.rel_minfaults = (int)(minfaults - st.base_minfaults);
487 st.rel_majfaults = (int)(majfaults - st.base_majfaults);
488 st.base_minfaults = minfaults;
489 st.base_majfaults = majfaults;
490 st.working = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800491 }
492
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800493 continue;
494 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700495
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800496 if (st == null || st.pid > pid) {
497 // We have a new process!
498 st = new Stats(pid, parentPid, mIncludeThreads);
499 allProcs.add(curStatsIndex, st);
500 curStatsIndex++;
501 NS++;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700502 if (DEBUG) Slog.v(TAG, "New "
503 + (parentPid < 0 ? "process" : "thread")
504 + " pid " + pid + ": " + st);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800505
506 final String[] procStatsString = mProcessFullStatsStringData;
507 final long[] procStats = mProcessFullStatsData;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700508 st.base_uptime = SystemClock.uptimeMillis();
Dianne Hackborn306af672014-06-24 15:41:03 -0700509 String path = st.statFile.toString();
510 //Slog.d(TAG, "Reading proc file: " + path);
511 if (Process.readProcFile(path, PROCESS_FULL_STATS_FORMAT, procStatsString,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800512 procStats, null)) {
Dianne Hackborn287952c2010-09-22 22:34:31 -0700513 // This is a possible way to filter out processes that
514 // are actually kernel threads... do we want to? Some
515 // of them do use CPU, but there can be a *lot* that are
516 // not doing anything.
Dianne Hackborn8e692572013-09-10 19:06:15 -0700517 st.vsize = procStats[PROCESS_FULL_STAT_VSIZE];
Dianne Hackborn287952c2010-09-22 22:34:31 -0700518 if (true || procStats[PROCESS_FULL_STAT_VSIZE] != 0) {
519 st.interesting = true;
520 st.baseName = procStatsString[0];
521 st.base_minfaults = procStats[PROCESS_FULL_STAT_MINOR_FAULTS];
522 st.base_majfaults = procStats[PROCESS_FULL_STAT_MAJOR_FAULTS];
Dianne Hackborn62793e42015-03-09 11:15:41 -0700523 st.base_utime = procStats[PROCESS_FULL_STAT_UTIME] * mJiffyMillis;
524 st.base_stime = procStats[PROCESS_FULL_STAT_STIME] * mJiffyMillis;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700525 } else {
526 Slog.i(TAG, "Skipping kernel process pid " + pid
527 + " name " + procStatsString[0]);
528 st.baseName = procStatsString[0];
529 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800530 } else {
Dianne Hackborn287952c2010-09-22 22:34:31 -0700531 Slog.w(TAG, "Skipping unknown process pid " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800532 st.baseName = "<unknown>";
533 st.base_utime = st.base_stime = 0;
Dianne Hackborn151ceb92009-08-06 12:40:56 -0700534 st.base_minfaults = st.base_majfaults = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800535 }
536
537 if (parentPid < 0) {
538 getName(st, st.cmdlineFile);
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700539 if (st.threadStats != null) {
540 mCurThreadPids = collectStats(st.threadsDir, pid, true,
541 mCurThreadPids, st.threadStats);
542 }
Dianne Hackborn287952c2010-09-22 22:34:31 -0700543 } else if (st.interesting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800544 st.name = st.baseName;
545 st.nameWidth = onMeasureProcessName(st.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800546 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700547
548 if (DEBUG) Slog.v("Load", "Stats added " + st.name + " pid=" + st.pid
549 + " utime=" + st.base_utime + " stime=" + st.base_stime
550 + " minfaults=" + st.base_minfaults + " majfaults=" + st.base_majfaults);
Dianne Hackbornd2932242013-08-05 18:18:42 -0700551
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800552 st.rel_utime = 0;
553 st.rel_stime = 0;
Dianne Hackborn151ceb92009-08-06 12:40:56 -0700554 st.rel_minfaults = 0;
555 st.rel_majfaults = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800556 st.added = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700557 if (!first && st.interesting) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700558 st.working = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800559 }
560 continue;
561 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700562
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800563 // This process has gone away!
564 st.rel_utime = 0;
565 st.rel_stime = 0;
Dianne Hackborn151ceb92009-08-06 12:40:56 -0700566 st.rel_minfaults = 0;
567 st.rel_majfaults = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800568 st.removed = true;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700569 st.working = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800570 allProcs.remove(curStatsIndex);
571 NS--;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700572 if (DEBUG) Slog.v(TAG, "Removed "
573 + (parentPid < 0 ? "process" : "thread")
574 + " pid " + pid + ": " + st);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800575 // Decrement the loop counter so that we process the current pid
576 // again the next time through the loop.
577 i--;
578 continue;
579 }
580
581 while (curStatsIndex < NS) {
582 // This process has gone away!
583 final Stats st = allProcs.get(curStatsIndex);
584 st.rel_utime = 0;
585 st.rel_stime = 0;
Dianne Hackborn151ceb92009-08-06 12:40:56 -0700586 st.rel_minfaults = 0;
587 st.rel_majfaults = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800588 st.removed = true;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700589 st.working = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800590 allProcs.remove(curStatsIndex);
591 NS--;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800592 if (localLOGV) Slog.v(TAG, "Removed pid " + st.pid + ": " + st);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800593 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800595 return pids;
596 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700597
Jeff Sharkey3e013e82013-04-25 14:48:19 -0700598 /**
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700599 * Returns the total time (in milliseconds) spent executing in
Dianne Hackborn652973f2014-09-10 17:08:48 -0700600 * both user and system code. Safe to call without lock held.
Jeff Sharkey3e013e82013-04-25 14:48:19 -0700601 */
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700602 public long getCpuTimeForPid(int pid) {
Dianne Hackborn652973f2014-09-10 17:08:48 -0700603 synchronized (mSinglePidStatsData) {
604 final String statFile = "/proc/" + pid + "/stat";
605 final long[] statsData = mSinglePidStatsData;
606 if (Process.readProcFile(statFile, PROCESS_STATS_FORMAT,
607 null, statsData, null)) {
608 long time = statsData[PROCESS_STAT_UTIME]
609 + statsData[PROCESS_STAT_STIME];
Dianne Hackborn62793e42015-03-09 11:15:41 -0700610 return time * mJiffyMillis;
Dianne Hackborn652973f2014-09-10 17:08:48 -0700611 }
612 return 0;
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700613 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700614 }
615
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 getLastUserTime() {
620 return mRelUserTime;
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 getLastSystemTime() {
627 return mRelSystemTime;
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 getLastIoWaitTime() {
634 return mRelIoWaitTime;
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 getLastIrqTime() {
641 return mRelIrqTime;
642 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700643
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700644 /**
645 * @return time in milliseconds.
646 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800647 final public int getLastSoftIrqTime() {
648 return mRelSoftIrqTime;
649 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700650
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700651 /**
652 * @return time in milliseconds.
653 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800654 final public int getLastIdleTime() {
655 return mRelIdleTime;
656 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700657
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800658 final public boolean hasGoodLastStats() {
659 return mRelStatsAreGood;
660 }
661
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800662 final public float getTotalCpuPercent() {
Dianne Hackborncdadee62012-06-06 11:48:46 -0700663 int denom = mRelUserTime+mRelSystemTime+mRelIrqTime+mRelIdleTime;
664 if (denom <= 0) {
665 return 0;
666 }
667 return ((float)(mRelUserTime+mRelSystemTime+mRelIrqTime)*100) / denom;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800668 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700669
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700670 final void buildWorkingProcs() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800671 if (!mWorkingProcsSorted) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700672 mWorkingProcs.clear();
673 final int N = mProcStats.size();
674 for (int i=0; i<N; i++) {
675 Stats stats = mProcStats.get(i);
676 if (stats.working) {
677 mWorkingProcs.add(stats);
678 if (stats.threadStats != null && stats.threadStats.size() > 1) {
679 stats.workingThreads.clear();
680 final int M = stats.threadStats.size();
681 for (int j=0; j<M; j++) {
682 Stats tstats = stats.threadStats.get(j);
683 if (tstats.working) {
684 stats.workingThreads.add(tstats);
685 }
686 }
687 Collections.sort(stats.workingThreads, sLoadComparator);
688 }
689 }
690 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800691 Collections.sort(mWorkingProcs, sLoadComparator);
692 mWorkingProcsSorted = true;
693 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700694 }
695
Dianne Hackborn287952c2010-09-22 22:34:31 -0700696 final public int countStats() {
697 return mProcStats.size();
698 }
699
700 final public Stats getStats(int index) {
701 return mProcStats.get(index);
702 }
703
Amith Yamasani10e8f162016-08-30 16:39:03 -0700704 final public List<Stats> getStats(FilterStats filter) {
705 final ArrayList<Stats> statses = new ArrayList<>(mProcStats.size());
706 final int N = mProcStats.size();
707 for (int p = 0; p < N; p++) {
708 Stats stats = mProcStats.get(p);
709 if (filter.needed(stats)) {
710 statses.add(stats);
711 }
712 }
713 return statses;
714 }
715
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700716 final public int countWorkingStats() {
717 buildWorkingProcs();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800718 return mWorkingProcs.size();
719 }
720
721 final public Stats getWorkingStats(int index) {
722 return mWorkingProcs.get(index);
723 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700724
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700725 final public String printCurrentLoad() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800726 StringWriter sw = new StringWriter();
Dianne Hackborn8c841092013-06-24 13:46:13 -0700727 PrintWriter pw = new FastPrintWriter(sw, false, 128);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800728 pw.print("Load: ");
729 pw.print(mLoad1);
730 pw.print(" / ");
731 pw.print(mLoad5);
732 pw.print(" / ");
733 pw.println(mLoad15);
Dianne Hackborn8c841092013-06-24 13:46:13 -0700734 pw.flush();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700735 return sw.toString();
736 }
737
738 final public String printCurrentState(long now) {
Joe Onoratod2bc2ba2016-04-15 13:34:25 -0700739 final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
740
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700741 buildWorkingProcs();
Dianne Hackbornd2932242013-08-05 18:18:42 -0700742
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700743 StringWriter sw = new StringWriter();
Dianne Hackborn8c841092013-06-24 13:46:13 -0700744 PrintWriter pw = new FastPrintWriter(sw, false, 1024);
Dianne Hackbornd2932242013-08-05 18:18:42 -0700745
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800746 pw.print("CPU usage from ");
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700747 if (now > mLastSampleTime) {
748 pw.print(now-mLastSampleTime);
749 pw.print("ms to ");
750 pw.print(now-mCurrentSampleTime);
751 pw.print("ms ago");
752 } else {
753 pw.print(mLastSampleTime-now);
754 pw.print("ms to ");
755 pw.print(mCurrentSampleTime-now);
756 pw.print("ms later");
757 }
Joe Onoratod2bc2ba2016-04-15 13:34:25 -0700758 pw.print(" (");
759 pw.print(sdf.format(new Date(mLastSampleWallTime)));
760 pw.print(" to ");
761 pw.print(sdf.format(new Date(mCurrentSampleWallTime)));
762 pw.print(")");
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700763
764 long sampleTime = mCurrentSampleTime - mLastSampleTime;
765 long sampleRealTime = mCurrentSampleRealTime - mLastSampleRealTime;
Dianne Hackborncdadee62012-06-06 11:48:46 -0700766 long percAwake = sampleRealTime > 0 ? ((sampleTime*100) / sampleRealTime) : 0;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700767 if (percAwake != 100) {
768 pw.print(" with ");
769 pw.print(percAwake);
770 pw.print("% awake");
771 }
772 pw.println(":");
Dianne Hackbornd2932242013-08-05 18:18:42 -0700773
Dianne Hackborn151ceb92009-08-06 12:40:56 -0700774 final int totalTime = mRelUserTime + mRelSystemTime + mRelIoWaitTime
775 + mRelIrqTime + mRelSoftIrqTime + mRelIdleTime;
Dianne Hackbornd2932242013-08-05 18:18:42 -0700776
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700777 if (DEBUG) Slog.i(TAG, "totalTime " + totalTime + " over sample time "
778 + (mCurrentSampleTime-mLastSampleTime));
779
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800780 int N = mWorkingProcs.size();
781 for (int i=0; i<N; i++) {
782 Stats st = mWorkingProcs.get(i);
783 printProcessCPU(pw, st.added ? " +" : (st.removed ? " -": " "),
Dianne Hackborn62793e42015-03-09 11:15:41 -0700784 st.pid, st.name, (int)st.rel_uptime,
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700785 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 -0800786 if (!st.removed && st.workingThreads != null) {
787 int M = st.workingThreads.size();
788 for (int j=0; j<M; j++) {
789 Stats tst = st.workingThreads.get(j);
790 printProcessCPU(pw,
791 tst.added ? " +" : (tst.removed ? " -": " "),
Dianne Hackborn62793e42015-03-09 11:15:41 -0700792 tst.pid, tst.name, (int)st.rel_uptime,
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700793 tst.rel_utime, tst.rel_stime, 0, 0, 0, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800794 }
795 }
796 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700797
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700798 printProcessCPU(pw, "", -1, "TOTAL", totalTime, mRelUserTime, mRelSystemTime,
Dianne Hackborn151ceb92009-08-06 12:40:56 -0700799 mRelIoWaitTime, mRelIrqTime, mRelSoftIrqTime, 0, 0);
Dianne Hackborn8c841092013-06-24 13:46:13 -0700800
801 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800802 return sw.toString();
803 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700804
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700805 private void printRatio(PrintWriter pw, long numerator, long denominator) {
806 long thousands = (numerator*1000)/denominator;
807 long hundreds = thousands/10;
808 pw.print(hundreds);
809 if (hundreds < 10) {
810 long remainder = thousands - (hundreds*10);
811 if (remainder != 0) {
812 pw.print('.');
813 pw.print(remainder);
814 }
815 }
816 }
817
818 private void printProcessCPU(PrintWriter pw, String prefix, int pid, String label,
819 int totalTime, int user, int system, int iowait, int irq, int softIrq,
820 int minFaults, int majFaults) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800821 pw.print(prefix);
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700822 if (totalTime == 0) totalTime = 1;
823 printRatio(pw, user+system+iowait+irq+softIrq, totalTime);
824 pw.print("% ");
825 if (pid >= 0) {
826 pw.print(pid);
827 pw.print("/");
828 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800829 pw.print(label);
830 pw.print(": ");
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700831 printRatio(pw, user, totalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800832 pw.print("% user + ");
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700833 printRatio(pw, system, totalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800834 pw.print("% kernel");
835 if (iowait > 0) {
836 pw.print(" + ");
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700837 printRatio(pw, iowait, totalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800838 pw.print("% iowait");
839 }
840 if (irq > 0) {
841 pw.print(" + ");
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700842 printRatio(pw, irq, totalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800843 pw.print("% irq");
844 }
845 if (softIrq > 0) {
846 pw.print(" + ");
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700847 printRatio(pw, softIrq, totalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800848 pw.print("% softirq");
849 }
Dianne Hackborn151ceb92009-08-06 12:40:56 -0700850 if (minFaults > 0 || majFaults > 0) {
851 pw.print(" / faults:");
852 if (minFaults > 0) {
853 pw.print(" ");
854 pw.print(minFaults);
855 pw.print(" minor");
856 }
857 if (majFaults > 0) {
858 pw.print(" ");
859 pw.print(majFaults);
860 pw.print(" major");
861 }
862 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800863 pw.println();
864 }
Dianne Hackbornd2932242013-08-05 18:18:42 -0700865
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800866 private String readFile(String file, char endChar) {
Dianne Hackborn8e8d65f2011-08-11 19:36:18 -0700867 // Permit disk reads here, as /proc/meminfo isn't really "on
868 // disk" and should be fast. TODO: make BlockGuard ignore
869 // /proc/ and /sys/ files perhaps?
870 StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
Brad Fitzpatrick6689ac82010-11-15 16:26:04 -0800871 FileInputStream is = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800872 try {
Brad Fitzpatrick6689ac82010-11-15 16:26:04 -0800873 is = new FileInputStream(file);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800874 int len = is.read(mBuffer);
875 is.close();
876
877 if (len > 0) {
878 int i;
879 for (i=0; i<len; i++) {
880 if (mBuffer[i] == endChar) {
881 break;
882 }
883 }
Christian Mehlmauer4136c982010-05-25 20:04:09 +0200884 return new String(mBuffer, 0, i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800885 }
886 } catch (java.io.FileNotFoundException e) {
887 } catch (java.io.IOException e) {
Brad Fitzpatrick6689ac82010-11-15 16:26:04 -0800888 } finally {
Jeff Sharkeyccce0162014-11-07 14:54:55 -0800889 IoUtils.closeQuietly(is);
Dianne Hackborn8e8d65f2011-08-11 19:36:18 -0700890 StrictMode.setThreadPolicy(savedPolicy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800891 }
892 return null;
893 }
894
895 private void getName(Stats st, String cmdlineFile) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700896 String newName = st.name;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700897 if (st.name == null || st.name.equals("app_process")
898 || st.name.equals("<pre-initialized>")) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800899 String cmdName = readFile(cmdlineFile, '\0');
900 if (cmdName != null && cmdName.length() > 1) {
901 newName = cmdName;
902 int i = newName.lastIndexOf("/");
903 if (i > 0 && i < newName.length()-1) {
904 newName = newName.substring(i+1);
905 }
906 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -0700907 if (newName == null) {
908 newName = st.baseName;
909 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800910 }
911 if (st.name == null || !newName.equals(st.name)) {
912 st.name = newName;
913 st.nameWidth = onMeasureProcessName(st.name);
914 }
915 }
916}