From 0d903a84d04d241a648ec429e3a0e82c712677fd Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Tue, 7 Sep 2010 23:51:03 -0700 Subject: [PATCH] People holding partial wake locks now get blamed for CPU usage. For the duration of the wake lock, 50% of all CPU usage is now accounted against the app(s) holding partial wake locks, evenly distributed between them. This is only while the device is on battery and screen off. Change-Id: I3e5c978b792b6ef17bf8540705bfe8343dadd464 --- core/java/android/os/BatteryStats.java | 6 +- .../android/internal/os/BatteryStatsImpl.java | 266 +++++++++++++++--- .../server/am/ActivityManagerService.java | 42 ++- .../com/android/server/am/ProcessRecord.java | 11 +- 4 files changed, 271 insertions(+), 54 deletions(-) diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index a857e582beafe..32fb108c593c9 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -1586,8 +1586,10 @@ public abstract class BatteryStats implements Parcelable { sb.append(prefix); sb.append(" CPU: "); formatTime(sb, userTime); sb.append("usr + "); formatTime(sb, systemTime); sb.append("krn\n"); - sb.append(prefix); sb.append(" "); sb.append(starts); - sb.append(" proc starts"); + if (starts != 0) { + sb.append(prefix); sb.append(" "); sb.append(starts); + sb.append(" proc starts"); + } pw.println(sb.toString()); for (int e=0; e> mSensorTimers = new SparseArray>(); + // Last partial timers we use for distributing CPU usage. + final ArrayList mLastPartialTimers = new ArrayList(); + // These are the objects that will want to do something when the device // is unplugged from power. final ArrayList mUnpluggables = new ArrayList(); @@ -240,6 +277,7 @@ public final class BatteryStatsImpl extends BatteryStats { // For debugging public BatteryStatsImpl() { mFile = null; + mHandler = null; } public static interface Unpluggable { @@ -739,7 +777,9 @@ public final class BatteryStatsImpl extends BatteryStats { * State for keeping track of timing information. */ public static final class StopwatchTimer extends Timer { + final Uid mUid; final ArrayList mTimerPool; + int mNesting; /** @@ -757,16 +797,24 @@ public final class BatteryStatsImpl extends BatteryStats { long mTimeout; - StopwatchTimer(int type, ArrayList timerPool, + /** + * For partial wake locks, keep track of whether we are in the list + * to consume CPU cycles. + */ + boolean mInList; + + StopwatchTimer(Uid uid, int type, ArrayList timerPool, ArrayList unpluggables, Parcel in) { super(type, unpluggables, in); + mUid = uid; mTimerPool = timerPool; mUpdateTime = in.readLong(); } - StopwatchTimer(int type, ArrayList timerPool, + StopwatchTimer(Uid uid, int type, ArrayList timerPool, ArrayList unpluggables) { super(type, unpluggables); + mUid = uid; mTimerPool = timerPool; } @@ -1252,6 +1300,10 @@ public final class BatteryStatsImpl extends BatteryStats { mWakeLockNesting++; } if (uid >= 0) { + if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) { + Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS); + mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS); + } getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type); } } @@ -1267,10 +1319,112 @@ public final class BatteryStatsImpl extends BatteryStats { } } if (uid >= 0) { + if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) { + Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS); + mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS); + } getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type); } } + public int startAddingCpuLocked() { + mHandler.removeMessages(MSG_UPDATE_WAKELOCKS); + + if (mScreenOn) { + return 0; + } + + final int N = mPartialTimers.size(); + if (N == 0) { + mLastPartialTimers.clear(); + return 0; + } + + // How many timers should consume CPU? Only want to include ones + // that have already been in the list. + for (int i=0; i(); mSensorTimers.put(mHandle, pool); } - return new StopwatchTimer(0, pool, unpluggables, in); + return new StopwatchTimer(Uid.this, 0, pool, unpluggables, in); } boolean reset() { @@ -3416,21 +3575,24 @@ public final class BatteryStatsImpl extends BatteryStats { case WAKE_TYPE_PARTIAL: t = wl.mTimerPartial; if (t == null) { - t = new StopwatchTimer(WAKE_TYPE_PARTIAL, mPartialTimers, mUnpluggables); + t = new StopwatchTimer(Uid.this, WAKE_TYPE_PARTIAL, + mPartialTimers, mUnpluggables); wl.mTimerPartial = t; } return t; case WAKE_TYPE_FULL: t = wl.mTimerFull; if (t == null) { - t = new StopwatchTimer(WAKE_TYPE_FULL, mFullTimers, mUnpluggables); + t = new StopwatchTimer(Uid.this, WAKE_TYPE_FULL, + mFullTimers, mUnpluggables); wl.mTimerFull = t; } return t; case WAKE_TYPE_WINDOW: t = wl.mTimerWindow; if (t == null) { - t = new StopwatchTimer(WAKE_TYPE_WINDOW, mWindowTimers, mUnpluggables); + t = new StopwatchTimer(Uid.this, WAKE_TYPE_WINDOW, + mWindowTimers, mUnpluggables); wl.mTimerWindow = t; } return t; @@ -3457,7 +3619,7 @@ public final class BatteryStatsImpl extends BatteryStats { timers = new ArrayList(); mSensorTimers.put(sensor, timers); } - t = new StopwatchTimer(BatteryStats.SENSOR, timers, mUnpluggables); + t = new StopwatchTimer(Uid.this, BatteryStats.SENSOR, timers, mUnpluggables); se.mTimer = t; return t; } @@ -3530,25 +3692,26 @@ public final class BatteryStatsImpl extends BatteryStats { public BatteryStatsImpl(String filename) { mFile = new JournaledFile(new File(filename), new File(filename + ".tmp")); + mHandler = new MyHandler(); mStartCount++; - mScreenOnTimer = new StopwatchTimer(-1, null, mUnpluggables); + mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables); for (int i=0; i