BatteryStats: Fix regression in wakelock power distribution
We used to give 50% of the cpu time of each app to any app holding a wakelock
while the screen is off.
Since we switched to the new kernel module for measuring app's cpu time, this distribution
was lost.
Bug:21876567
Change-Id: I42c294547f63d150d9929271ca0e27fedaaa9d77
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index d165240..153efe4 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -4017,8 +4017,10 @@
if (userCpuTimeUs > 0 || systemCpuTimeUs > 0) {
sb.setLength(0);
sb.append(prefix);
- sb.append(" Total cpu time: ");
- formatTimeMs(sb, (userCpuTimeUs + systemCpuTimeUs) / 1000);
+ sb.append(" Total cpu time: u=");
+ formatTimeMs(sb, userCpuTimeUs / 1000);
+ sb.append("s=");
+ formatTimeMs(sb, systemCpuTimeUs / 1000);
pw.println(sb.toString());
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 07d1fc8..159b8db 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -96,6 +96,7 @@
private static final String TAG = "BatteryStatsImpl";
private static final boolean DEBUG = false;
private static final boolean DEBUG_ENERGY = false;
+ public static final boolean DEBUG_ENERGY_CPU = DEBUG_ENERGY || false;
private static final boolean DEBUG_HISTORY = false;
private static final boolean USE_OLD_HISTORY = false; // for debugging.
@@ -151,6 +152,9 @@
BatteryCallback cb = mCallback;
switch (msg.what) {
case MSG_UPDATE_WAKELOCKS:
+ synchronized (BatteryStatsImpl.this) {
+ updateCpuTimeLocked();
+ }
if (cb != null) {
cb.batteryNeedsCpuUpdate();
}
@@ -2503,12 +2507,11 @@
boolean unpluggedScreenOff = unplugged && screenOff;
if (unpluggedScreenOff != mOnBatteryScreenOffTimeBase.isRunning()) {
updateKernelWakelocksLocked();
- requestWakelockCpuUpdate();
- if (!unpluggedScreenOff) {
- // We are switching to no longer tracking wake locks, but we want
- // the next CPU update we receive to take them in to account.
- mDistributeWakelockCpu = true;
+ if (DEBUG_ENERGY_CPU) {
+ Slog.d(TAG, "Updating cpu time because screen is now " +
+ (unpluggedScreenOff ? "off" : "on"));
}
+ updateCpuTimeLocked();
mOnBatteryScreenOffTimeBase.setRunning(unpluggedScreenOff, uptime, realtime);
}
}
@@ -2772,10 +2775,14 @@
mWakeLockNesting++;
}
if (uid >= 0) {
- //if (uid == 0) {
- // Slog.wtf(TAG, "Acquiring wake lock from root: " + name);
- //}
- requestWakelockCpuUpdate();
+ if (mOnBatteryScreenOffTimeBase.isRunning()) {
+ // We only update the cpu time when a wake lock is acquired if the screen is off.
+ // If the screen is on, we don't distribute the power amongst partial wakelocks.
+ if (DEBUG_ENERGY_CPU) {
+ Slog.d(TAG, "Updating cpu time because of +wake_lock");
+ }
+ requestWakelockCpuUpdate();
+ }
getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type, elapsedRealtime);
}
}
@@ -2805,7 +2812,12 @@
}
}
if (uid >= 0) {
- requestWakelockCpuUpdate();
+ if (mOnBatteryScreenOffTimeBase.isRunning()) {
+ if (DEBUG_ENERGY_CPU) {
+ Slog.d(TAG, "Updating cpu time because of -wake_lock");
+ }
+ requestWakelockCpuUpdate();
+ }
getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type, elapsedRealtime);
}
}
@@ -2874,46 +2886,14 @@
addHistoryRecordLocked(elapsedRealtime, uptime);
}
- public int startAddingCpuLocked() {
+ public boolean startAddingCpuLocked() {
mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
-
- if (!mOnBatteryInternal) {
- return -1;
- }
-
- final int N = mPartialTimers.size();
- if (N == 0) {
- mLastPartialTimers.clear();
- mDistributeWakelockCpu = false;
- return 0;
- }
-
- if (!mOnBatteryScreenOffTimeBase.isRunning() && !mDistributeWakelockCpu) {
- return 0;
- }
-
- mDistributeWakelockCpu = false;
-
- // How many timers should consume CPU? Only want to include ones
- // that have already been in the list.
- for (int i=0; i<N; i++) {
- StopwatchTimer st = mPartialTimers.get(i);
- if (st.mInList) {
- Uid uid = st.mUid;
- // We don't include the system UID, because it so often
- // holds wake locks at one request or another of an app.
- if (uid != null && uid.mUid != Process.SYSTEM_UID) {
- return 50;
- }
- }
- }
-
- return 0;
+ return mOnBatteryInternal;
}
- public void finishAddingCpuLocked(int perc, int remainUTime, int remainSTtime,
- int totalUTime, int totalSTime, int statUserTime, int statSystemTime,
- int statIOWaitTime, int statIrqTime, int statSoftIrqTime, int statIdleTime) {
+ public void finishAddingCpuLocked(int totalUTime, int totalSTime, int statUserTime,
+ int statSystemTime, int statIOWaitTime, int statIrqTime,
+ int statSoftIrqTime, int statIdleTime) {
if (DEBUG) Slog.d(TAG, "Adding cpu: tuser=" + totalUTime + " tsys=" + totalSTime
+ " user=" + statUserTime + " sys=" + statSystemTime
+ " io=" + statIOWaitTime + " irq=" + statIrqTime
@@ -2926,70 +2906,6 @@
mCurStepStatIrqTime += statIrqTime;
mCurStepStatSoftIrqTime += statSoftIrqTime;
mCurStepStatIdleTime += statIdleTime;
-
- final int N = mPartialTimers.size();
- if (perc != 0) {
- int num = 0;
- for (int i=0; i<N; i++) {
- StopwatchTimer st = mPartialTimers.get(i);
- if (st.mInList) {
- Uid uid = st.mUid;
- // We don't include the system UID, because it so often
- // holds wake locks at one request or another of an app.
- if (uid != null && uid.mUid != Process.SYSTEM_UID) {
- num++;
- }
- }
- }
- if (num != 0) {
- for (int i=0; i<N; i++) {
- StopwatchTimer st = mPartialTimers.get(i);
- if (st.mInList) {
- Uid uid = st.mUid;
- if (uid != null && uid.mUid != Process.SYSTEM_UID) {
- int myUTime = remainUTime/num;
- int mySTime = remainSTtime/num;
- remainUTime -= myUTime;
- remainSTtime -= mySTime;
- num--;
- Uid.Proc proc = uid.getProcessStatsLocked("*wakelock*");
- proc.addCpuTimeLocked(myUTime, mySTime);
- }
- }
- }
- }
-
- // Just in case, collect any lost CPU time.
- if (remainUTime != 0 || remainSTtime != 0) {
- Uid uid = getUidStatsLocked(Process.SYSTEM_UID);
- if (uid != null) {
- Uid.Proc proc = uid.getProcessStatsLocked("*lost*");
- proc.addCpuTimeLocked(remainUTime, remainSTtime);
- }
- }
- }
-
- final int NL = mLastPartialTimers.size();
- boolean diff = N != NL;
- for (int i=0; i<NL && !diff; i++) {
- diff |= mPartialTimers.get(i) != mLastPartialTimers.get(i);
- }
- if (!diff) {
- for (int i=0; i<NL; i++) {
- mPartialTimers.get(i).mInList = true;
- }
- return;
- }
-
- for (int i=0; i<NL; i++) {
- mLastPartialTimers.get(i).mInList = false;
- }
- mLastPartialTimers.clear();
- for (int i=0; i<N; i++) {
- StopwatchTimer st = mPartialTimers.get(i);
- st.mInList = true;
- mLastPartialTimers.add(st);
- }
}
public void noteProcessDiedLocked(int uid, int pid) {
@@ -7959,30 +7875,196 @@
}
}
+ // We use an anonymous class to access these variables,
+ // so they can't live on the stack or they'd have to be
+ // final MutableLong objects (more allocations).
+ // Used in updateCpuTimeLocked().
+ long mTempTotalCpuUserTimeUs;
+ long mTempTotalCpuSystemTimeUs;
+
/**
- * Read and distribute CPU usage across apps.
+ * Read and distribute CPU usage across apps. If their are partial wakelocks being held
+ * and we are on battery with screen off, we give more of the cpu time to those apps holding
+ * wakelocks. If the screen is on, we just assign the actual cpu time an app used.
*/
- public void updateCpuTimeLocked(boolean firstTime) {
+ public void updateCpuTimeLocked() {
+ if (DEBUG_ENERGY_CPU) {
+ Slog.d(TAG, "!Cpu updating!");
+ }
+
+ // Holding a wakelock costs more than just using the cpu.
+ // Currently, we assign only half the cpu time to an app that is running but
+ // not holding a wakelock. The apps holding wakelocks get the rest of the blame.
+ // If no app is holding a wakelock, then the distribution is normal.
+ final int wakelockWeight = 50;
+
+ // Read the time spent at various cpu frequencies.
final int cpuSpeedSteps = getCpuSpeedSteps();
final long[] cpuSpeeds = mKernelCpuSpeedReader.readDelta();
- KernelUidCpuTimeReader.Callback callback = null;
- if (mOnBatteryInternal && !firstTime) {
- callback = new KernelUidCpuTimeReader.Callback() {
- @Override
- public void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs) {
- final Uid u = getUidStatsLocked(mapUid(uid));
- u.mUserCpuTime.addCountLocked(userTimeUs);
- u.mSystemCpuTime.addCountLocked(systemTimeUs);
- for (int i = 0; i < cpuSpeedSteps; i++) {
- if (u.mSpeedBins[i] == null) {
- u.mSpeedBins[i] = new LongSamplingCounter(mOnBatteryTimeBase);
- }
- u.mSpeedBins[i].addCountLocked(cpuSpeeds[i]);
- }
+
+ int numWakelocks = 0;
+
+ // Calculate how many wakelocks we have to distribute amongst. The system is excluded.
+ // Only distribute cpu power to wakelocks if the screen is off and we're on battery.
+ final int numPartialTimers = mPartialTimers.size();
+ if (mOnBatteryScreenOffTimeBase.isRunning()) {
+ for (int i = 0; i < numPartialTimers; i++) {
+ final StopwatchTimer timer = mPartialTimers.get(i);
+ if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) {
+ // Since the collection and blaming of wakelocks can be scheduled to run after
+ // some delay, the mPartialTimers list may have new entries. We can't blame
+ // the newly added timer for past cpu time, so we only consider timers that
+ // were present for one round of collection. Once a timer has gone through
+ // a round of collection, its mInList field is set to true.
+ numWakelocks++;
}
- };
+ }
}
- mKernelUidCpuTimeReader.readDelta(callback);
+
+ final int numWakelocksF = numWakelocks;
+ mTempTotalCpuUserTimeUs = 0;
+ mTempTotalCpuSystemTimeUs = 0;
+
+ // Read the CPU data for each UID. This will internally generate a snapshot so next time
+ // we read, we get a delta. If we are to distribute the cpu time, then do so. Otherwise
+ // we just ignore the data.
+ final long startTimeMs = SystemClock.elapsedRealtime();
+ mKernelUidCpuTimeReader.readDelta(!mOnBatteryInternal ? null :
+ new KernelUidCpuTimeReader.Callback() {
+ @Override
+ public void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs) {
+ final Uid u = getUidStatsLocked(mapUid(uid));
+
+ // Accumulate the total system and user time.
+ mTempTotalCpuUserTimeUs += userTimeUs;
+ mTempTotalCpuSystemTimeUs += systemTimeUs;
+
+ StringBuilder sb = null;
+ if (DEBUG_ENERGY_CPU) {
+ sb = new StringBuilder();
+ sb.append(" got time for uid=").append(u.mUid).append(": u=");
+ TimeUtils.formatDuration(userTimeUs / 1000, sb);
+ sb.append(" s=");
+ TimeUtils.formatDuration(systemTimeUs / 1000, sb);
+ sb.append("\n");
+ }
+
+ if (numWakelocksF > 0) {
+ // We have wakelocks being held, so only give a portion of the
+ // time to the process. The rest will be distributed among wakelock
+ // holders.
+ userTimeUs = (userTimeUs * wakelockWeight) / 100;
+ systemTimeUs = (systemTimeUs * wakelockWeight) / 100;
+ }
+
+ if (sb != null) {
+ sb.append(" adding to uid=").append(u.mUid).append(": u=");
+ TimeUtils.formatDuration(userTimeUs / 1000, sb);
+ sb.append(" s=");
+ TimeUtils.formatDuration(systemTimeUs / 1000, sb);
+ Slog.d(TAG, sb.toString());
+ }
+
+ u.mUserCpuTime.addCountLocked(userTimeUs);
+ u.mSystemCpuTime.addCountLocked(systemTimeUs);
+
+ // Add the cpu speeds to this UID. These are used as a ratio
+ // for computing the power this UID used.
+ for (int i = 0; i < cpuSpeedSteps; i++) {
+ if (u.mSpeedBins[i] == null) {
+ u.mSpeedBins[i] = new LongSamplingCounter(mOnBatteryTimeBase);
+ }
+ u.mSpeedBins[i].addCountLocked(cpuSpeeds[i]);
+ }
+ }
+ });
+
+ if (DEBUG_ENERGY_CPU) {
+ Slog.d(TAG, "Reading cpu stats took " + (SystemClock.elapsedRealtime() - startTimeMs) +
+ " ms");
+ }
+
+ if (mOnBatteryInternal && numWakelocks > 0) {
+ // Distribute a portion of the total cpu time to wakelock holders.
+ mTempTotalCpuUserTimeUs = (mTempTotalCpuUserTimeUs * (100 - wakelockWeight)) / 100;
+ mTempTotalCpuSystemTimeUs =
+ (mTempTotalCpuSystemTimeUs * (100 - wakelockWeight)) / 100;
+
+ for (int i = 0; i < numPartialTimers; i++) {
+ final StopwatchTimer timer = mPartialTimers.get(i);
+
+ // The system does not share any blame, as it is usually holding the wakelock
+ // on behalf of an app.
+ if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) {
+ int userTimeUs = (int) (mTempTotalCpuUserTimeUs / numWakelocks);
+ int systemTimeUs = (int) (mTempTotalCpuSystemTimeUs / numWakelocks);
+
+ if (DEBUG_ENERGY_CPU) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(" Distributing wakelock uid=").append(timer.mUid.mUid)
+ .append(": u=");
+ TimeUtils.formatDuration(userTimeUs / 1000, sb);
+ sb.append(" s=");
+ TimeUtils.formatDuration(systemTimeUs / 1000, sb);
+ Slog.d(TAG, sb.toString());
+ }
+
+ timer.mUid.mUserCpuTime.addCountLocked(userTimeUs);
+ timer.mUid.mSystemCpuTime.addCountLocked(systemTimeUs);
+
+ final Uid.Proc proc = timer.mUid.getProcessStatsLocked("*wakelock*");
+ proc.addCpuTimeLocked(userTimeUs, systemTimeUs);
+
+ mTempTotalCpuUserTimeUs -= userTimeUs;
+ mTempTotalCpuSystemTimeUs -= systemTimeUs;
+ numWakelocks--;
+ }
+ }
+
+ if (mTempTotalCpuUserTimeUs > 0 || mTempTotalCpuSystemTimeUs > 0) {
+ // Anything left over is given to the system.
+ if (DEBUG_ENERGY_CPU) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(" Distributing lost time to system: u=");
+ TimeUtils.formatDuration(mTempTotalCpuUserTimeUs / 1000, sb);
+ sb.append(" s=");
+ TimeUtils.formatDuration(mTempTotalCpuSystemTimeUs / 1000, sb);
+ Slog.d(TAG, sb.toString());
+ }
+
+ final Uid u = getUidStatsLocked(Process.SYSTEM_UID);
+ u.mUserCpuTime.addCountLocked(mTempTotalCpuUserTimeUs);
+ u.mSystemCpuTime.addCountLocked(mTempTotalCpuSystemTimeUs);
+
+ final Uid.Proc proc = u.getProcessStatsLocked("*lost*");
+ proc.addCpuTimeLocked((int) mTempTotalCpuUserTimeUs,
+ (int) mTempTotalCpuSystemTimeUs);
+ }
+ }
+
+ // See if there is a difference in wakelocks between this collection and the last
+ // collection.
+ if (ArrayUtils.referenceEquals(mPartialTimers, mLastPartialTimers)) {
+ // No difference, so each timer is now considered for the next collection.
+ for (int i = 0; i < numPartialTimers; i++) {
+ mPartialTimers.get(i).mInList = true;
+ }
+ } else {
+ // The lists are different, meaning we added (or removed a timer) since the last
+ // collection.
+ final int numLastPartialTimers = mLastPartialTimers.size();
+ for (int i = 0; i < numLastPartialTimers; i++) {
+ mLastPartialTimers.get(i).mInList = false;
+ }
+ mLastPartialTimers.clear();
+
+ // Mark the current timers as gone through a collection.
+ for (int i = 0; i < numPartialTimers; i++) {
+ final StopwatchTimer timer = mPartialTimers.get(i);
+ timer.mInList = true;
+ mLastPartialTimers.add(timer);
+ }
+ }
}
boolean setChargingLocked(boolean charging) {
diff --git a/core/java/com/android/internal/os/KernelUidCpuTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
index b236378..62926d1 100644
--- a/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
+++ b/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
@@ -16,9 +16,11 @@
package com.android.internal.os;
import android.annotation.Nullable;
+import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Slog;
import android.util.SparseLongArray;
+import android.util.TimeUtils;
import java.io.BufferedReader;
import java.io.FileReader;
@@ -49,6 +51,7 @@
private SparseLongArray mLastUserTimeUs = new SparseLongArray();
private SparseLongArray mLastSystemTimeUs = new SparseLongArray();
+ private long mLastTimeRead = 0;
/**
* Reads the proc file, calling into the callback with a delta of time for each UID.
@@ -57,6 +60,7 @@
* a fresh delta.
*/
public void readDelta(@Nullable Callback callback) {
+ long now = SystemClock.elapsedRealtime();
try (BufferedReader reader = new BufferedReader(new FileReader(sProcFile))) {
TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter(' ');
String line;
@@ -75,10 +79,32 @@
userTimeDeltaUs -= mLastUserTimeUs.valueAt(index);
systemTimeDeltaUs -= mLastSystemTimeUs.valueAt(index);
- if (userTimeDeltaUs < 0 || systemTimeDeltaUs < 0) {
- // The UID must have been removed from accounting, then added back.
- userTimeDeltaUs = userTimeUs;
- systemTimeDeltaUs = systemTimeUs;
+ final long timeDiffMs = (now - mLastTimeRead) * 1000;
+ if (userTimeDeltaUs < 0 || systemTimeDeltaUs < 0 ||
+ userTimeDeltaUs > timeDiffMs || systemTimeDeltaUs > timeDiffMs ) {
+ StringBuilder sb = new StringBuilder("Malformed cpu data!\n");
+ sb.append("Time between reads: ");
+ TimeUtils.formatDuration(timeDiffMs, sb);
+ sb.append("ms\n");
+ sb.append("Previous times: u=");
+ TimeUtils.formatDuration(mLastUserTimeUs.valueAt(index) / 1000, sb);
+ sb.append("ms s=");
+ TimeUtils.formatDuration(mLastSystemTimeUs.valueAt(index) / 1000, sb);
+ sb.append("ms\n");
+ sb.append("Current times: u=");
+ TimeUtils.formatDuration(userTimeUs / 1000, sb);
+ sb.append("ms s=");
+ TimeUtils.formatDuration(systemTimeUs / 1000, sb);
+ sb.append("ms\n");
+ sb.append("Delta for UID=").append(uid).append(": u=");
+ TimeUtils.formatDuration(userTimeDeltaUs / 1000, sb);
+ sb.append("ms s=");
+ TimeUtils.formatDuration(systemTimeDeltaUs / 1000, sb);
+ sb.append("ms");
+ Slog.wtf(TAG, sb.toString());
+
+ userTimeDeltaUs = 0;
+ systemTimeDeltaUs = 0;
}
}
@@ -92,6 +118,7 @@
} catch (IOException e) {
Slog.e(TAG, "Failed to read uid_cputime", e);
}
+ mLastTimeRead = now;
}
/**
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index 62e724a..9d0636a 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -387,4 +387,26 @@
public static <T> boolean contains(ArrayList<T> cur, T val) {
return (cur != null) ? cur.contains(val) : false;
}
+
+ /**
+ * Returns true if the two ArrayLists are equal with respect to the objects they contain.
+ * The objects must be in the same order and be reference equal (== not .equals()).
+ */
+ public static <T> boolean referenceEquals(ArrayList<T> a, ArrayList<T> b) {
+ if (a == b) {
+ return true;
+ }
+
+ final int sizeA = a.size();
+ final int sizeB = b.size();
+ if (a == null || b == null || sizeA != sizeB) {
+ return false;
+ }
+
+ boolean diff = false;
+ for (int i = 0; i < sizeA && !diff; i++) {
+ diff |= a.get(i) != b.get(i);
+ }
+ return !diff;
+ }
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e9b9767..d288904 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2482,10 +2482,7 @@
synchronized(bstats) {
synchronized(mPidsSelfLocked) {
if (haveNewCpuStats) {
- final int perc = bstats.startAddingCpuLocked();
- if (perc >= 0) {
- int remainUTime = 0;
- int remainSTime = 0;
+ if (bstats.startAddingCpuLocked()) {
int totalUTime = 0;
int totalSTime = 0;
final int N = mProcessCpuTracker.countStats();
@@ -2495,10 +2492,6 @@
continue;
}
ProcessRecord pr = mPidsSelfLocked.get(st.pid);
- int otherUTime = (st.rel_utime*perc)/100;
- int otherSTime = (st.rel_stime*perc)/100;
- remainUTime += otherUTime;
- remainSTime += otherSTime;
totalUTime += st.rel_utime;
totalSTime += st.rel_stime;
if (pr != null) {
@@ -2507,8 +2500,7 @@
pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
pr.info.uid, pr.processName);
}
- ps.addCpuTimeLocked(st.rel_utime - otherUTime,
- st.rel_stime - otherSTime);
+ ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
pr.curCpuTime += st.rel_utime + st.rel_stime;
} else {
BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
@@ -2516,8 +2508,7 @@
st.batteryStats = ps = bstats.getProcessStatsLocked(
bstats.mapUid(st.uid), st.name);
}
- ps.addCpuTimeLocked(st.rel_utime - otherUTime,
- st.rel_stime - otherSTime);
+ ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
}
}
final int userTime = mProcessCpuTracker.getLastUserTime();
@@ -2526,9 +2517,8 @@
final int irqTime = mProcessCpuTracker.getLastIrqTime();
final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
final int idleTime = mProcessCpuTracker.getLastIdleTime();
- bstats.finishAddingCpuLocked(perc, remainUTime,
- remainSTime, totalUTime, totalSTime, userTime, systemTime,
- iowaitTime, irqTime, softIrqTime, idleTime);
+ bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
+ systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
}
}
}
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index c973386..b3189cd 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -64,7 +64,6 @@
implements PowerManagerInternal.LowPowerModeListener {
static final String TAG = "BatteryStatsService";
- private boolean mFirstExternalStatsUpdate = true;
static IBatteryStats sService;
final BatteryStatsImpl mStats;
final BatteryStatsHandler mHandler;
@@ -807,7 +806,7 @@
// Sync external stats first as the battery has changed states. If we don't sync
// immediately here, we may not collect the relevant data later.
- updateExternalStats("battery-state", false);
+ updateExternalStats("battery-state", true);
synchronized (mStats) {
mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt);
}
@@ -1217,18 +1216,16 @@
mStats.addHistoryEventLocked(elapsedRealtime, uptime,
BatteryStats.HistoryItem.EVENT_COLLECT_EXTERNAL_STATS, reason, 0);
}
- mStats.updateCpuTimeLocked(mFirstExternalStatsUpdate);
+
+ if (BatteryStatsImpl.DEBUG_ENERGY_CPU) {
+ Slog.d(TAG, "Updating cpu time from external: " + reason);
+ }
+ mStats.updateCpuTimeLocked();
mStats.updateKernelWakelocksLocked();
mStats.updateMobileRadioStateLocked(SystemClock.elapsedRealtime());
mStats.updateWifiStateLocked(wifiEnergyInfo);
mStats.updateBluetoothStateLocked(bluetoothEnergyInfo);
}
-
- if (mFirstExternalStatsUpdate) {
- // We have read the stats for the first time, which means we have a baseline
- // from which to calculate delta.
- mFirstExternalStatsUpdate = false;
- }
}
}
}