am 4718afcd: am 14b57010: Merge "BatteryStats: Record cpu power usage from /proc/uid_cputime" into mnc-dev
* commit '4718afcd2e5d52638ba1c4f58b2db6aea01171de': BatteryStats: Record cpu power usage from /proc/uid_cputime
This commit is contained in:
@@ -184,6 +184,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
private static final String UID_DATA = "uid";
|
||||
private static final String APK_DATA = "apk";
|
||||
private static final String PROCESS_DATA = "pr";
|
||||
private static final String CPU_DATA = "cpu";
|
||||
private static final String SENSOR_DATA = "sr";
|
||||
private static final String VIBRATOR_DATA = "vib";
|
||||
private static final String FOREGROUND_DATA = "fg";
|
||||
@@ -456,9 +457,14 @@ public abstract class BatteryStats implements Parcelable {
|
||||
*/
|
||||
public abstract long getSystemCpuTimeUs(int which);
|
||||
|
||||
/**
|
||||
* Get the total cpu power consumed (in milli-ampere-microseconds).
|
||||
*/
|
||||
public abstract long getCpuPowerMaUs(int which);
|
||||
|
||||
/**
|
||||
* Returns the approximate cpu time (in milliseconds) spent at a certain CPU speed.
|
||||
* @param speedStep the index of the CPU speed. This is not the actual speed of the CPU.
|
||||
* @param step the index of the CPU speed. This is not the actual speed of the CPU.
|
||||
* @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
|
||||
* @see BatteryStats#getCpuSpeedSteps()
|
||||
*/
|
||||
@@ -2905,6 +2911,14 @@ public abstract class BatteryStats implements Parcelable {
|
||||
dumpLine(pw, uid, category, STATE_TIME_DATA, stateTimes);
|
||||
}
|
||||
|
||||
final long userCpuTimeUs = u.getUserCpuTimeUs(which);
|
||||
final long systemCpuTimeUs = u.getSystemCpuTimeUs(which);
|
||||
final long powerCpuMaUs = u.getCpuPowerMaUs(which);
|
||||
if (userCpuTimeUs > 0 || systemCpuTimeUs > 0 || powerCpuMaUs > 0) {
|
||||
dumpLine(pw, uid, category, CPU_DATA, userCpuTimeUs / 1000, systemCpuTimeUs / 1000,
|
||||
powerCpuMaUs / 1000);
|
||||
}
|
||||
|
||||
final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats
|
||||
= u.getProcessStats();
|
||||
for (int ipr=processStats.size()-1; ipr>=0; ipr--) {
|
||||
@@ -2970,6 +2984,10 @@ public abstract class BatteryStats implements Parcelable {
|
||||
printer.print(BatteryStatsHelper.makemAh(power));
|
||||
}
|
||||
|
||||
private void printmAh(StringBuilder sb, double power) {
|
||||
sb.append(BatteryStatsHelper.makemAh(power));
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporary for settings.
|
||||
*/
|
||||
@@ -4028,13 +4046,17 @@ public abstract class BatteryStats implements Parcelable {
|
||||
|
||||
final long userCpuTimeUs = u.getUserCpuTimeUs(which);
|
||||
final long systemCpuTimeUs = u.getSystemCpuTimeUs(which);
|
||||
if (userCpuTimeUs > 0 || systemCpuTimeUs > 0) {
|
||||
final long powerCpuMaUs = u.getCpuPowerMaUs(which);
|
||||
if (userCpuTimeUs > 0 || systemCpuTimeUs > 0 || powerCpuMaUs > 0) {
|
||||
sb.setLength(0);
|
||||
sb.append(prefix);
|
||||
sb.append(" Total cpu time: u=");
|
||||
formatTimeMs(sb, userCpuTimeUs / 1000);
|
||||
sb.append("s=");
|
||||
formatTimeMs(sb, systemCpuTimeUs / 1000);
|
||||
sb.append("p=");
|
||||
printmAh(sb, powerCpuMaUs / (1000.0 * 1000.0 * 60.0 * 60.0));
|
||||
sb.append("mAh");
|
||||
pw.println(sb.toString());
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
|
||||
|
||||
// Current on-disk Parcel version
|
||||
private static final int VERSION = 129 + (USE_OLD_HISTORY ? 1000 : 0);
|
||||
private static final int VERSION = 130 + (USE_OLD_HISTORY ? 1000 : 0);
|
||||
|
||||
// Maximum number of items we will record in the history.
|
||||
private static final int MAX_HISTORY_ITEMS = 2000;
|
||||
@@ -4386,6 +4386,7 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
|
||||
LongSamplingCounter mUserCpuTime = new LongSamplingCounter(mOnBatteryTimeBase);
|
||||
LongSamplingCounter mSystemCpuTime = new LongSamplingCounter(mOnBatteryTimeBase);
|
||||
LongSamplingCounter mCpuPower = new LongSamplingCounter(mOnBatteryTimeBase);
|
||||
LongSamplingCounter[] mSpeedBins;
|
||||
|
||||
/**
|
||||
@@ -4977,6 +4978,11 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
return mSystemCpuTime.getCountLocked(which);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCpuPowerMaUs(int which) {
|
||||
return mCpuPower.getCountLocked(which);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTimeAtCpuSpeed(int step, int which) {
|
||||
if (step >= 0 && step < mSpeedBins.length) {
|
||||
@@ -5097,6 +5103,7 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
|
||||
mUserCpuTime.reset(false);
|
||||
mSystemCpuTime.reset(false);
|
||||
mCpuPower.reset(false);
|
||||
for (int i = 0; i < mSpeedBins.length; i++) {
|
||||
LongSamplingCounter c = mSpeedBins[i];
|
||||
if (c != null) {
|
||||
@@ -5248,6 +5255,7 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
|
||||
mUserCpuTime.detach();
|
||||
mSystemCpuTime.detach();
|
||||
mCpuPower.detach();
|
||||
for (int i = 0; i < mSpeedBins.length; i++) {
|
||||
LongSamplingCounter c = mSpeedBins[i];
|
||||
if (c != null) {
|
||||
@@ -5427,6 +5435,7 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
|
||||
mUserCpuTime.writeToParcel(out);
|
||||
mSystemCpuTime.writeToParcel(out);
|
||||
mCpuPower.writeToParcel(out);
|
||||
|
||||
out.writeInt(mSpeedBins.length);
|
||||
for (int i = 0; i < mSpeedBins.length; i++) {
|
||||
@@ -5618,6 +5627,7 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
|
||||
mUserCpuTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
|
||||
mSystemCpuTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
|
||||
mCpuPower = new LongSamplingCounter(mOnBatteryTimeBase, in);
|
||||
|
||||
int bins = in.readInt();
|
||||
int steps = getCpuSpeedSteps();
|
||||
@@ -7964,7 +7974,8 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
mKernelUidCpuTimeReader.readDelta(!mOnBatteryInternal ? null :
|
||||
new KernelUidCpuTimeReader.Callback() {
|
||||
@Override
|
||||
public void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs) {
|
||||
public void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs,
|
||||
long powerMaUs) {
|
||||
final Uid u = getUidStatsLocked(mapUid(uid));
|
||||
|
||||
// Accumulate the total system and user time.
|
||||
@@ -7978,7 +7989,7 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
TimeUtils.formatDuration(userTimeUs / 1000, sb);
|
||||
sb.append(" s=");
|
||||
TimeUtils.formatDuration(systemTimeUs / 1000, sb);
|
||||
sb.append("\n");
|
||||
sb.append(" p=").append(powerMaUs / 1000).append("mAms\n");
|
||||
}
|
||||
|
||||
if (numWakelocksF > 0) {
|
||||
@@ -7994,11 +8005,13 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
TimeUtils.formatDuration(userTimeUs / 1000, sb);
|
||||
sb.append(" s=");
|
||||
TimeUtils.formatDuration(systemTimeUs / 1000, sb);
|
||||
sb.append(" p=").append(powerMaUs / 1000).append("mAms");
|
||||
Slog.d(TAG, sb.toString());
|
||||
}
|
||||
|
||||
u.mUserCpuTime.addCountLocked(userTimeUs);
|
||||
u.mSystemCpuTime.addCountLocked(systemTimeUs);
|
||||
u.mCpuPower.addCountLocked(powerMaUs);
|
||||
|
||||
// Add the cpu speeds to this UID. These are used as a ratio
|
||||
// for computing the power this UID used.
|
||||
@@ -9229,6 +9242,7 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
|
||||
u.mUserCpuTime.readSummaryFromParcelLocked(in);
|
||||
u.mSystemCpuTime.readSummaryFromParcelLocked(in);
|
||||
u.mCpuPower.readSummaryFromParcelLocked(in);
|
||||
|
||||
int NSB = in.readInt();
|
||||
if (NSB > 100) {
|
||||
@@ -9575,6 +9589,7 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
|
||||
u.mUserCpuTime.writeSummaryFromParcelLocked(out);
|
||||
u.mSystemCpuTime.writeSummaryFromParcelLocked(out);
|
||||
u.mCpuPower.writeSummaryFromParcelLocked(out);
|
||||
|
||||
out.writeInt(u.mSpeedBins.length);
|
||||
for (int i = 0; i < u.mSpeedBins.length; i++) {
|
||||
|
||||
@@ -30,7 +30,7 @@ import java.io.IOException;
|
||||
/**
|
||||
* Reads /proc/uid_cputime/show_uid_stat which has the line format:
|
||||
*
|
||||
* uid: user_time_micro_seconds system_time_micro_seconds
|
||||
* uid: user_time_micro_seconds system_time_micro_seconds power_in_milli-amp-micro_seconds
|
||||
*
|
||||
* This provides the time a UID's processes spent executing in user-space and kernel-space.
|
||||
* The file contains a monotonically increasing count of time for a single boot. This class
|
||||
@@ -46,11 +46,18 @@ public class KernelUidCpuTimeReader {
|
||||
* Callback interface for processing each line of the proc file.
|
||||
*/
|
||||
public interface Callback {
|
||||
void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs);
|
||||
/**
|
||||
* @param uid UID of the app
|
||||
* @param userTimeUs time spent executing in user space in microseconds
|
||||
* @param systemTimeUs time spent executing in kernel space in microseconds
|
||||
* @param powerMaUs power consumed executing, in milli-ampere microseconds
|
||||
*/
|
||||
void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs, long powerMaUs);
|
||||
}
|
||||
|
||||
private SparseLongArray mLastUserTimeUs = new SparseLongArray();
|
||||
private SparseLongArray mLastSystemTimeUs = new SparseLongArray();
|
||||
private SparseLongArray mLastPowerMaUs = new SparseLongArray();
|
||||
private long mLastTimeReadUs = 0;
|
||||
|
||||
/**
|
||||
@@ -70,50 +77,60 @@ public class KernelUidCpuTimeReader {
|
||||
final int uid = Integer.parseInt(uidStr.substring(0, uidStr.length() - 1), 10);
|
||||
final long userTimeUs = Long.parseLong(splitter.next(), 10);
|
||||
final long systemTimeUs = Long.parseLong(splitter.next(), 10);
|
||||
final long powerMaUs = Long.parseLong(splitter.next(), 10) / 1000;
|
||||
|
||||
if (callback != null) {
|
||||
long userTimeDeltaUs = userTimeUs;
|
||||
long systemTimeDeltaUs = systemTimeUs;
|
||||
long powerDeltaMaUs = powerMaUs;
|
||||
int index = mLastUserTimeUs.indexOfKey(uid);
|
||||
if (index >= 0) {
|
||||
userTimeDeltaUs -= mLastUserTimeUs.valueAt(index);
|
||||
systemTimeDeltaUs -= mLastSystemTimeUs.valueAt(index);
|
||||
powerDeltaMaUs -= mLastPowerMaUs.valueAt(index);
|
||||
|
||||
final long timeDiffUs = nowUs - mLastTimeReadUs;
|
||||
if (userTimeDeltaUs < 0 || systemTimeDeltaUs < 0 ||
|
||||
if (userTimeDeltaUs < 0 || systemTimeDeltaUs < 0 || powerDeltaMaUs < 0 ||
|
||||
userTimeDeltaUs > timeDiffUs || systemTimeDeltaUs > timeDiffUs) {
|
||||
StringBuilder sb = new StringBuilder("Malformed cpu data!\n");
|
||||
StringBuilder sb = new StringBuilder("Malformed cpu data for UID=");
|
||||
sb.append(uid).append("!\n");
|
||||
sb.append("Time between reads: ");
|
||||
TimeUtils.formatDuration(timeDiffUs / 1000, sb);
|
||||
sb.append("ms\n");
|
||||
sb.append("\n");
|
||||
sb.append("Previous times: u=");
|
||||
TimeUtils.formatDuration(mLastUserTimeUs.valueAt(index) / 1000, sb);
|
||||
sb.append("ms s=");
|
||||
sb.append(" s=");
|
||||
TimeUtils.formatDuration(mLastSystemTimeUs.valueAt(index) / 1000, sb);
|
||||
sb.append("ms\n");
|
||||
sb.append(" p=").append(mLastPowerMaUs.valueAt(index) / 1000);
|
||||
sb.append("mAms\n");
|
||||
|
||||
sb.append("Current times: u=");
|
||||
TimeUtils.formatDuration(userTimeUs / 1000, sb);
|
||||
sb.append("ms s=");
|
||||
sb.append(" s=");
|
||||
TimeUtils.formatDuration(systemTimeUs / 1000, sb);
|
||||
sb.append("ms\n");
|
||||
sb.append("Delta for UID=").append(uid).append(": u=");
|
||||
sb.append(" p=").append(powerMaUs / 1000);
|
||||
sb.append("mAms\n");
|
||||
sb.append("Delta: u=");
|
||||
TimeUtils.formatDuration(userTimeDeltaUs / 1000, sb);
|
||||
sb.append("ms s=");
|
||||
sb.append(" s=");
|
||||
TimeUtils.formatDuration(systemTimeDeltaUs / 1000, sb);
|
||||
sb.append("ms");
|
||||
sb.append(" p=").append(powerDeltaMaUs / 1000).append("mAms");
|
||||
Slog.wtf(TAG, sb.toString());
|
||||
|
||||
userTimeDeltaUs = 0;
|
||||
systemTimeDeltaUs = 0;
|
||||
powerDeltaMaUs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (userTimeDeltaUs != 0 || systemTimeDeltaUs != 0) {
|
||||
callback.onUidCpuTime(uid, userTimeDeltaUs, systemTimeDeltaUs);
|
||||
if (userTimeDeltaUs != 0 || systemTimeDeltaUs != 0 || powerDeltaMaUs != 0) {
|
||||
callback.onUidCpuTime(uid, userTimeDeltaUs, systemTimeDeltaUs,
|
||||
powerDeltaMaUs);
|
||||
}
|
||||
}
|
||||
mLastUserTimeUs.put(uid, userTimeUs);
|
||||
mLastSystemTimeUs.put(uid, systemTimeUs);
|
||||
mLastPowerMaUs.put(uid, powerMaUs);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Slog.e(TAG, "Failed to read uid_cputime", e);
|
||||
|
||||
Reference in New Issue
Block a user