Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(67)

Side by Side Diff: webrtc/examples/androidapp/src/org/appspot/apprtc/CpuMonitor.java

Issue 1951663002: Update CPU monitor to use moving averages. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc@master
Patch Set: Rename tags Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | webrtc/examples/androidapp/src/org/appspot/apprtc/HudFragment.java » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2015 The WebRTC Project Authors. All rights reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 package org.appspot.apprtc; 11 package org.appspot.apprtc;
12 12
13 import android.content.Context; 13 import android.content.Context;
14 import android.content.Intent; 14 import android.content.Intent;
15 import android.content.IntentFilter; 15 import android.content.IntentFilter;
16 import android.os.BatteryManager; 16 import android.os.BatteryManager;
17 import android.os.Environment;
18 import android.os.SystemClock; 17 import android.os.SystemClock;
19 import android.util.Log; 18 import android.util.Log;
20 19
21 import java.io.BufferedReader; 20 import java.io.BufferedReader;
22 import java.io.File;
23 import java.io.FileNotFoundException; 21 import java.io.FileNotFoundException;
24 import java.io.FileOutputStream;
25 import java.io.FileReader; 22 import java.io.FileReader;
26 import java.io.IOException; 23 import java.io.IOException;
27 import java.text.SimpleDateFormat; 24 import java.util.Arrays;
28 import java.util.Calendar;
29 import java.util.Date;
30 import java.util.Scanner; 25 import java.util.Scanner;
31 26
32 import org.appspot.apprtc.util.LooperExecutor; 27 import org.appspot.apprtc.util.LooperExecutor;
33 28
34 /** 29 /**
35 * Simple CPU monitor. The caller creates a CpuMonitor object which can then 30 * Simple CPU monitor. The caller creates a CpuMonitor object which can then
36 * be used via sampleCpuUtilization() to collect the percentual use of the 31 * be used via sampleCpuUtilization() to collect the percentual use of the
37 * cumulative CPU capacity for all CPUs running at their nominal frequency. 3 32 * cumulative CPU capacity for all CPUs running at their nominal frequency. 3
38 * values are generated: (1) getCpuCurrent() returns the use since the last 33 * values are generated: (1) getCpuCurrent() returns the use since the last
39 * sampleCpuUtilization(), (2) getCpuAvg3() returns the use since 3 prior 34 * sampleCpuUtilization(), (2) getCpuAvg3() returns the use since 3 prior
(...skipping 28 matching lines...) Expand all
68 * 63 *
69 * <p>Known problems: 64 * <p>Known problems:
70 * 1. Nexus 7 devices running Kitkat have a kernel which often output an 65 * 1. Nexus 7 devices running Kitkat have a kernel which often output an
71 * incorrect 'idle' field in /proc/stat. The value is close to twice the 66 * incorrect 'idle' field in /proc/stat. The value is close to twice the
72 * correct value, and then returns to back to correct reading. Both when 67 * correct value, and then returns to back to correct reading. Both when
73 * jumping up and back down we might create faulty CPU load readings. 68 * jumping up and back down we might create faulty CPU load readings.
74 */ 69 */
75 70
76 class CpuMonitor { 71 class CpuMonitor {
77 private static final String TAG = "CpuMonitor"; 72 private static final String TAG = "CpuMonitor";
78 private static final String DUMP_FILE = "cpu_log.txt"; 73 private static final int MOVING_AVERAGE_SAMPLES = 10;
79 private static final int CPU_STAT_SAMPLE_PERIOD = 2000; 74
80 private static final int CPU_STAT_LOG_PERIOD = 6000; 75 private static final int CPU_STAT_SAMPLE_PERIOD_MS = 1000;
76 private static final int CPU_STAT_LOG_PERIOD_MS = 5000;
81 77
82 private final Context appContext; 78 private final Context appContext;
79 // User CPU usage at current frequency.
80 private final MovingAverage userCpuUsage;
81 // System CPU usage at current frequency.
82 private final MovingAverage systemCpuUsage;
83 // Total CPU usage relative to maximum frequency.
84 private final MovingAverage totalCpuUsage;
85 // CPU frequency in percentage from maximum.
86 private final MovingAverage frequencyScale;
87
83 private LooperExecutor executor; 88 private LooperExecutor executor;
84 private long lastStatLogTimeMs; 89 private long lastStatLogTimeMs;
85 private int iterations;
86 private double currentUserCpuUsage;
87 private double currentSystemCpuUsage;
88 private double currentTotalCpuUsage;
89 private double currentFrequencyScale = -1;
90 private double sumUserCpuUsage;
91 private double sumSystemCpuUsage;
92 private double sumFrequencyScale;
93 private double sumTotalCpuUsage;
94 private long[] cpuFreqMax; 90 private long[] cpuFreqMax;
95 private int cpusPresent; 91 private int cpusPresent;
96 private int actualCpusPresent; 92 private int actualCpusPresent;
97 private boolean initialized = false; 93 private boolean initialized;
94 private boolean cpuOveruse;
98 private String[] maxPath; 95 private String[] maxPath;
99 private String[] curPath; 96 private String[] curPath;
100 private double[] curFreqScales; 97 private double[] curFreqScales;
101 private ProcStat lastProcStat; 98 private ProcStat lastProcStat;
102 99
103 private static boolean dumpEnabled = false; 100 private static class ProcStat {
104 private static FileOutputStream fileWriter;
105
106 private class ProcStat {
107 final long userTime; 101 final long userTime;
108 final long systemTime; 102 final long systemTime;
109 final long idleTime; 103 final long idleTime;
110 104
111 ProcStat(long userTime, long systemTime, long idleTime) { 105 ProcStat(long userTime, long systemTime, long idleTime) {
112 this.userTime = userTime; 106 this.userTime = userTime;
113 this.systemTime = systemTime; 107 this.systemTime = systemTime;
114 this.idleTime = idleTime; 108 this.idleTime = idleTime;
115 } 109 }
116 } 110 }
117 111
112 private static class MovingAverage {
113 private final int size;
114 private double sum;
115 private double currentValue;
116 private double circBuffer[];
117 private int circBufferIndex;
118
119 public MovingAverage(int size) {
120 if (size <= 0) {
121 throw new AssertionError("Size value in MovingAverage ctor should be pos itive.");
122 }
123 this.size = size;
124 circBuffer = new double[size];
125 }
126
127 public void reset() {
128 Arrays.fill(circBuffer, 0);
129 circBufferIndex = 0;
130 sum = 0;
131 currentValue = 0;
132 }
133
134 public void addValue(double value) {
135 sum -= circBuffer[circBufferIndex];
136 circBuffer[circBufferIndex++] = value;
137 currentValue = value;
138 sum += value;
139 if (circBufferIndex >= size) {
140 circBufferIndex = 0;
141 }
142 }
143
144 public double getCurrent() {
145 return currentValue;
146 }
147
148 public double getAverage() {
149 return sum / (double) size;
150 }
151 }
152
118 public CpuMonitor(Context context) { 153 public CpuMonitor(Context context) {
119 Log.d(TAG, "CpuMonitor ctor."); 154 Log.d(TAG, "CpuMonitor ctor.");
120 appContext = context.getApplicationContext(); 155 appContext = context.getApplicationContext();
121 lastStatLogTimeMs = 0; 156 userCpuUsage = new MovingAverage(MOVING_AVERAGE_SAMPLES);
157 systemCpuUsage = new MovingAverage(MOVING_AVERAGE_SAMPLES);
158 totalCpuUsage = new MovingAverage(MOVING_AVERAGE_SAMPLES);
159 frequencyScale = new MovingAverage(MOVING_AVERAGE_SAMPLES);
160 lastStatLogTimeMs = SystemClock.elapsedRealtime();
122 161
123 executor = new LooperExecutor(); 162 executor = new LooperExecutor();
124 executor.requestStart(); 163 executor.requestStart();
125 scheduleCpuUtilizationTask(); 164 scheduleCpuUtilizationTask();
126 } 165 }
127 166
128 public void release() { 167 public void release() {
129 if (executor != null) { 168 if (executor != null) {
130 Log.d(TAG, "release"); 169 Log.d(TAG, "release");
131 executor.cancelScheduledTasks(); 170 executor.cancelScheduledTasks();
(...skipping 10 matching lines...) Expand all
142 } 181 }
143 182
144 public void resume() { 183 public void resume() {
145 if (executor != null) { 184 if (executor != null) {
146 Log.d(TAG, "resume"); 185 Log.d(TAG, "resume");
147 resetStat(); 186 resetStat();
148 scheduleCpuUtilizationTask(); 187 scheduleCpuUtilizationTask();
149 } 188 }
150 } 189 }
151 190
191 public synchronized void reset() {
192 if (executor != null) {
193 Log.d(TAG, "reset");
194 resetStat();
195 cpuOveruse = false;
196 }
197 }
198
152 public synchronized int getCpuUsageCurrent() { 199 public synchronized int getCpuUsageCurrent() {
153 return doubleToPercent(currentTotalCpuUsage); 200 return doubleToPercent(userCpuUsage.getCurrent() + systemCpuUsage.getCurrent ());
154 } 201 }
155 202
156 public synchronized int getCpuUsageAverage() { 203 public synchronized int getCpuUsageAverage() {
157 return sumDoubleToPercent(sumTotalCpuUsage, iterations); 204 return doubleToPercent(userCpuUsage.getAverage() + systemCpuUsage.getAverage ());
158 } 205 }
159 206
160 public synchronized int getCpuFrequencyScaleCurrent() { 207 public synchronized int getFrequencyScaleAverage() {
161 return doubleToPercent(currentFrequencyScale); 208 return doubleToPercent(frequencyScale.getAverage());
162 } 209 }
163 210
164 private void scheduleCpuUtilizationTask() { 211 private void scheduleCpuUtilizationTask() {
165 executor.scheduleAtFixedRate(new Runnable() { 212 executor.scheduleAtFixedRate(new Runnable() {
166 @Override 213 @Override
167 public void run() { 214 public void run() {
168 logCpuUtilization(); 215 cpuUtilizationTask();
169 } 216 }
170 }, CPU_STAT_SAMPLE_PERIOD); 217 }, CPU_STAT_SAMPLE_PERIOD_MS);
171 } 218 }
172 219
173 private void checkDump(String statString) { 220 private void cpuUtilizationTask() {
174 if (!dumpEnabled) { 221 boolean cpuMonitorAvailable = sampleCpuUtilization();
175 return; 222 if (cpuMonitorAvailable
176 } 223 && SystemClock.elapsedRealtime() - lastStatLogTimeMs >= CPU_STAT_LOG_PER IOD_MS) {
177 if (fileWriter == null) { 224 lastStatLogTimeMs = SystemClock.elapsedRealtime();
178 Log.d(TAG, "Start log dump"); 225 String statString = getStatString();
179 String fileName = Environment.getExternalStorageDirectory().getAbsolutePat h() 226 Log.d(TAG, statString);
180 + File.separator + DUMP_FILE;
181 try {
182 fileWriter = new FileOutputStream(fileName, false /* append */);
183 } catch (FileNotFoundException e) {
184 Log.e(TAG, "Can not open file.", e);
185 dumpEnabled = false;
186 return;
187 }
188 }
189
190 Date date = Calendar.getInstance().getTime();
191 SimpleDateFormat df = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
192 String msg = df.format(date) + " " + TAG + ":" + statString + "\n";
193 try {
194 fileWriter.write(msg.getBytes());
195 } catch (IOException e) {
196 Log.e(TAG, "Can not write to file.", e);
197 dumpEnabled = false;
198 } 227 }
199 } 228 }
200 229
201 private void logCpuUtilization() {
202 boolean logStatistics = false;
203 if (SystemClock.elapsedRealtime() - lastStatLogTimeMs >= CPU_STAT_LOG_PERIOD ) {
204 lastStatLogTimeMs = SystemClock.elapsedRealtime();
205 logStatistics = true;
206 }
207 boolean cpuMonitorAvailable = sampleCpuUtilization();
208 if (logStatistics && cpuMonitorAvailable) {
209 String statString = getStatString();
210 checkDump(statString);
211 Log.d(TAG, statString);
212 resetStat();
213 }
214 }
215
216 private void init() { 230 private void init() {
217 try { 231 try {
218 FileReader fin = new FileReader("/sys/devices/system/cpu/present"); 232 FileReader fin = new FileReader("/sys/devices/system/cpu/present");
219 try { 233 try {
220 BufferedReader reader = new BufferedReader(fin); 234 BufferedReader reader = new BufferedReader(fin);
221 Scanner scanner = new Scanner(reader).useDelimiter("[-\n]"); 235 Scanner scanner = new Scanner(reader).useDelimiter("[-\n]");
222 scanner.nextInt(); // Skip leading number 0. 236 scanner.nextInt(); // Skip leading number 0.
223 cpusPresent = 1 + scanner.nextInt(); 237 cpusPresent = 1 + scanner.nextInt();
224 scanner.close(); 238 scanner.close();
225 } catch (Exception e) { 239 } catch (Exception e) {
(...skipping 18 matching lines...) Expand all
244 curPath[i] = "/sys/devices/system/cpu/cpu" + i + "/cpufreq/scaling_cur_fre q"; 258 curPath[i] = "/sys/devices/system/cpu/cpu" + i + "/cpufreq/scaling_cur_fre q";
245 } 259 }
246 260
247 lastProcStat = new ProcStat(0, 0, 0); 261 lastProcStat = new ProcStat(0, 0, 0);
248 resetStat(); 262 resetStat();
249 263
250 initialized = true; 264 initialized = true;
251 } 265 }
252 266
253 private synchronized void resetStat() { 267 private synchronized void resetStat() {
254 sumUserCpuUsage = 0; 268 userCpuUsage.reset();
255 sumSystemCpuUsage = 0; 269 systemCpuUsage.reset();
256 sumFrequencyScale = 0; 270 totalCpuUsage.reset();
257 sumTotalCpuUsage = 0; 271 frequencyScale.reset();
258 iterations = 0; 272 lastStatLogTimeMs = SystemClock.elapsedRealtime();
259 } 273 }
260 274
261 private int getBatteryLevel() { 275 private int getBatteryLevel() {
262 // Use sticky broadcast with null receiver to read battery level once only. 276 // Use sticky broadcast with null receiver to read battery level once only.
263 Intent intent = appContext.registerReceiver( 277 Intent intent = appContext.registerReceiver(
264 null /* receiver */, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 278 null /* receiver */, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
265 279
266 int batteryLevel = 0; 280 int batteryLevel = 0;
267 int batteryScale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100); 281 int batteryScale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
268 if (batteryScale > 0) { 282 if (batteryScale > 0) {
(...skipping 29 matching lines...) Expand all
298 * For each CPU, attempt to first read its max frequency, then its 312 * For each CPU, attempt to first read its max frequency, then its
299 * current frequency. Once as the max frequency for a CPU is found, 313 * current frequency. Once as the max frequency for a CPU is found,
300 * save it in cpuFreqMax[]. 314 * save it in cpuFreqMax[].
301 */ 315 */
302 316
303 curFreqScales[i] = 0; 317 curFreqScales[i] = 0;
304 if (cpuFreqMax[i] == 0) { 318 if (cpuFreqMax[i] == 0) {
305 // We have never found this CPU's max frequency. Attempt to read it. 319 // We have never found this CPU's max frequency. Attempt to read it.
306 long cpufreqMax = readFreqFromFile(maxPath[i]); 320 long cpufreqMax = readFreqFromFile(maxPath[i]);
307 if (cpufreqMax > 0) { 321 if (cpufreqMax > 0) {
322 Log.d(TAG, "Core " + i + ". Max frequency: " + cpufreqMax);
308 lastSeenMaxFreq = cpufreqMax; 323 lastSeenMaxFreq = cpufreqMax;
309 cpuFreqMax[i] = cpufreqMax; 324 cpuFreqMax[i] = cpufreqMax;
310 maxPath[i] = null; // Kill path to free its memory. 325 maxPath[i] = null; // Kill path to free its memory.
311 } 326 }
312 } else { 327 } else {
313 lastSeenMaxFreq = cpuFreqMax[i]; // A valid, previously read value. 328 lastSeenMaxFreq = cpuFreqMax[i]; // A valid, previously read value.
314 } 329 }
315 330
316 long cpuFreqCur = readFreqFromFile(curPath[i]); 331 long cpuFreqCur = readFreqFromFile(curPath[i]);
317 if (cpuFreqCur == 0 && lastSeenMaxFreq == 0) { 332 if (cpuFreqCur == 0 && lastSeenMaxFreq == 0) {
(...skipping 22 matching lines...) Expand all
340 return false; 355 return false;
341 } 356 }
342 357
343 /* 358 /*
344 * Since the cycle counts are for the period between the last invocation 359 * Since the cycle counts are for the period between the last invocation
345 * and this present one, we average the percentual CPU frequencies between 360 * and this present one, we average the percentual CPU frequencies between
346 * now and the beginning of the measurement period. This is significantly 361 * now and the beginning of the measurement period. This is significantly
347 * incorrect only if the frequencies have peeked or dropped in between the 362 * incorrect only if the frequencies have peeked or dropped in between the
348 * invocations. 363 * invocations.
349 */ 364 */
350 double newFrequencyScale = (double) cpuFreqCurSum / cpuFreqMaxSum; 365 double currentFrequencyScale = cpuFreqCurSum / (double) cpuFreqMaxSum;
351 double frequencyScale; 366 if (frequencyScale.getCurrent() > 0) {
352 if (currentFrequencyScale > 0) { 367 currentFrequencyScale = (frequencyScale.getCurrent() + currentFrequencySca le) * 0.5;
353 frequencyScale = (currentFrequencyScale + newFrequencyScale) * 0.5;
354 } else {
355 frequencyScale = newFrequencyScale;
356 } 368 }
357 369
358 ProcStat procStat = readProcStat(); 370 ProcStat procStat = readProcStat();
359 if (procStat == null) { 371 if (procStat == null) {
360 return false; 372 return false;
361 } 373 }
362 374
363 long diffUserTime = procStat.userTime - lastProcStat.userTime; 375 long diffUserTime = procStat.userTime - lastProcStat.userTime;
364 long diffSystemTime = procStat.systemTime - lastProcStat.systemTime; 376 long diffSystemTime = procStat.systemTime - lastProcStat.systemTime;
365 long diffIdleTime = procStat.idleTime - lastProcStat.idleTime; 377 long diffIdleTime = procStat.idleTime - lastProcStat.idleTime;
366 long allTime = diffUserTime + diffSystemTime + diffIdleTime; 378 long allTime = diffUserTime + diffSystemTime + diffIdleTime;
367 379
368 if (frequencyScale == 0 || allTime == 0) { 380 if (currentFrequencyScale == 0 || allTime == 0) {
369 return false; 381 return false;
370 } 382 }
371 383
372 // Update statistics. 384 // Update statistics.
373 currentFrequencyScale = frequencyScale; 385 frequencyScale.addValue(currentFrequencyScale);
374 sumFrequencyScale += frequencyScale;
375 386
376 currentUserCpuUsage = (double) diffUserTime / allTime; 387 double currentUserCpuUsage = diffUserTime / (double) allTime;
377 sumUserCpuUsage += currentUserCpuUsage; 388 userCpuUsage.addValue(currentUserCpuUsage);
378 389
379 currentSystemCpuUsage = (double) diffSystemTime / allTime; 390 double currentSystemCpuUsage = diffSystemTime / (double) allTime;
380 sumSystemCpuUsage += currentSystemCpuUsage; 391 systemCpuUsage.addValue(currentSystemCpuUsage);
381 392
382 currentTotalCpuUsage = (currentUserCpuUsage + currentSystemCpuUsage) * curre ntFrequencyScale; 393 double currentTotalCpuUsage =
383 sumTotalCpuUsage += currentTotalCpuUsage; 394 (currentUserCpuUsage + currentSystemCpuUsage) * currentFrequencyScale;
395 totalCpuUsage.addValue(currentTotalCpuUsage);
384 396
385 iterations++;
386 // Save new measurements for next round's deltas. 397 // Save new measurements for next round's deltas.
387 lastProcStat = procStat; 398 lastProcStat = procStat;
388 399
389 return true; 400 return true;
390 } 401 }
391 402
392 private int doubleToPercent(double d) { 403 private int doubleToPercent(double d) {
393 return (int) (d * 100 + 0.5); 404 return (int) (d * 100 + 0.5);
394 } 405 }
395 406
396 private int sumDoubleToPercent(double d, int iterations) { 407 private synchronized String getStatString() {
397 if (iterations > 0) {
398 return (int) (d * 100.0 / (double) iterations + 0.5);
399 } else {
400 return 0;
401 }
402 }
403
404 private String getStatString() {
405 StringBuilder stat = new StringBuilder(); 408 StringBuilder stat = new StringBuilder();
406 stat.append("CPU User: ") 409 stat.append("CPU User: ")
407 .append(doubleToPercent(currentUserCpuUsage)).append("/") 410 .append(doubleToPercent(userCpuUsage.getCurrent())).append("/")
408 .append(sumDoubleToPercent(sumUserCpuUsage, iterations)).append(" (") 411 .append(doubleToPercent(userCpuUsage.getAverage()))
409 .append(doubleToPercent(currentUserCpuUsage * currentFrequencyScale)).ap pend(")")
410 .append(". System: ") 412 .append(". System: ")
411 .append(doubleToPercent(currentSystemCpuUsage)).append("/") 413 .append(doubleToPercent(systemCpuUsage.getCurrent())).append("/")
412 .append(sumDoubleToPercent(sumSystemCpuUsage, iterations)).append(" (") 414 .append(doubleToPercent(systemCpuUsage.getAverage()))
413 .append(doubleToPercent(currentSystemCpuUsage * currentFrequencyScale)). append(")") 415 .append(". Freq: ")
414 .append(". CPU freq %: ") 416 .append(doubleToPercent(frequencyScale.getCurrent())).append("/")
415 .append(doubleToPercent(currentFrequencyScale)).append("/") 417 .append(doubleToPercent(frequencyScale.getAverage()))
416 .append(sumDoubleToPercent(sumFrequencyScale, iterations)) 418 .append(". Total usage: ")
417 .append(". Total CPU usage: ") 419 .append(doubleToPercent(totalCpuUsage.getCurrent())).append("/")
418 .append(doubleToPercent(currentTotalCpuUsage)).append("/") 420 .append(doubleToPercent(totalCpuUsage.getAverage()))
419 .append(sumDoubleToPercent(sumTotalCpuUsage, iterations))
420 .append(". Cores: ") 421 .append(". Cores: ")
421 .append(actualCpusPresent); 422 .append(actualCpusPresent);
422 stat.append("( "); 423 stat.append("( ");
423 for (int i = 0; i < cpusPresent; i++) { 424 for (int i = 0; i < cpusPresent; i++) {
424 stat.append(doubleToPercent(curFreqScales[i])).append(" "); 425 stat.append(doubleToPercent(curFreqScales[i])).append(" ");
425 } 426 }
426 stat.append("). Battery %: ") 427 stat.append("). Battery: ").append(getBatteryLevel());
427 .append(getBatteryLevel()); 428 if (cpuOveruse) {
429 stat.append(". Overuse.");
430 }
428 return stat.toString(); 431 return stat.toString();
429 } 432 }
430 433
431 /** 434 /**
432 * Read a single integer value from the named file. Return the read value 435 * Read a single integer value from the named file. Return the read value
433 * or if an error occurs return 0. 436 * or if an error occurs return 0.
434 */ 437 */
435 private long readFreqFromFile(String fileName) { 438 private long readFreqFromFile(String fileName) {
436 long number = 0; 439 long number = 0;
437 try { 440 try {
(...skipping 23 matching lines...) Expand all
461 private ProcStat readProcStat() { 464 private ProcStat readProcStat() {
462 long userTime = 0; 465 long userTime = 0;
463 long systemTime = 0; 466 long systemTime = 0;
464 long idleTime = 0; 467 long idleTime = 0;
465 try { 468 try {
466 FileReader fin = new FileReader("/proc/stat"); 469 FileReader fin = new FileReader("/proc/stat");
467 try { 470 try {
468 BufferedReader rdr = new BufferedReader(fin); 471 BufferedReader rdr = new BufferedReader(fin);
469 Scanner scanner = new Scanner(rdr); 472 Scanner scanner = new Scanner(rdr);
470 scanner.next(); 473 scanner.next();
471 userTime = scanner.nextLong(); 474 userTime = scanner.nextLong(); // user
472 long nice = scanner.nextLong(); 475 long nice = scanner.nextLong(); // nice
473 userTime += nice; 476 userTime += nice;
474 systemTime = scanner.nextLong(); 477 systemTime = scanner.nextLong(); // system
475 idleTime = scanner.nextLong(); 478 idleTime = scanner.nextLong(); // idle
476 long ioWaitTime = scanner.nextLong(); 479 long ioWaitTime = scanner.nextLong(); // iowait
477 userTime += ioWaitTime; 480 userTime += ioWaitTime;
481 long irqTime = scanner.nextLong() + scanner.nextLong(); // irq + softirq
482 systemTime += irqTime;
478 scanner.close(); 483 scanner.close();
479 } catch (Exception e) { 484 } catch (Exception e) {
480 Log.e(TAG, "Problems parsing /proc/stat"); 485 Log.e(TAG, "Problems parsing /proc/stat");
481 return null; 486 return null;
482 } finally { 487 } finally {
483 fin.close(); 488 fin.close();
484 } 489 }
485 } catch (FileNotFoundException e) { 490 } catch (FileNotFoundException e) {
486 Log.e(TAG, "Cannot open /proc/stat for reading"); 491 Log.e(TAG, "Cannot open /proc/stat for reading");
487 return null; 492 return null;
488 } catch (IOException e) { 493 } catch (IOException e) {
489 Log.e(TAG, "Problems reading /proc/stat"); 494 Log.e(TAG, "Problems reading /proc/stat");
490 return null; 495 return null;
491 } 496 }
492 return new ProcStat(userTime, systemTime, idleTime); 497 return new ProcStat(userTime, systemTime, idleTime);
493 } 498 }
494 } 499 }
OLDNEW
« no previous file with comments | « no previous file | webrtc/examples/androidapp/src/org/appspot/apprtc/HudFragment.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698