From 62a9ff67184381c1543e8851cd34424183afac7a Mon Sep 17 00:00:00 2001 From: Michael Wachenschwanz Date: Mon, 24 May 2021 21:54:06 -0700 Subject: [PATCH] Move RPM stats collection out of BatteryStatsImpl.mLock Querying RPM stats on device with a large number of StateResidency info can take a long time. Move the query to outside of the BatteryStats lock to reduce the chance of lock contention. Bug: 185970842 Test: atest android.cts.statsd.validation.ValidationTests#testPartialWakelock Change-Id: I1c69b3f9c071e5d758cf4b22855c4b0ec221a5cf --- .../android/internal/os/BatteryStatsImpl.java | 27 ++++++++++++++----- .../server/am/BatteryExternalStatsWorker.java | 3 +++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index be059a1e195ba..a68a007dad568 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -275,7 +275,7 @@ public class BatteryStatsImpl extends BatteryStats { private int mNumAllUidCpuTimeReads; /** Container for Resource Power Manager stats. Updated by updateRpmStatsLocked. */ - private final RpmStats mTmpRpmStats = new RpmStats(); + private RpmStats mTmpRpmStats = null; /** The soonest the RPM stats can be updated after it was last updated. */ private static final long RPM_STATS_UPDATE_FREQ_MS = 1000; /** Last time that RPM stats were updated by updateRpmStatsLocked. */ @@ -12387,19 +12387,34 @@ public class BatteryStatsImpl extends BatteryStats { mLastBluetoothActivityInfo.set(info); } - /** - * Read and record Resource Power Manager (RPM) state and voter times. + * Read Resource Power Manager (RPM) state and voter times. * If RPM stats were fetched more recently than RPM_STATS_UPDATE_FREQ_MS ago, uses the old data * instead of fetching it anew. + * + * Note: This should be called without synchronizing this BatteryStatsImpl object */ - public void updateRpmStatsLocked(long elapsedRealtimeUs) { + public void fillLowPowerStats() { if (mPlatformIdleStateCallback == null) return; + + RpmStats rpmStats = new RpmStats(); long now = SystemClock.elapsedRealtime(); if (now - mLastRpmStatsUpdateTimeMs >= RPM_STATS_UPDATE_FREQ_MS) { - mPlatformIdleStateCallback.fillLowPowerStats(mTmpRpmStats); - mLastRpmStatsUpdateTimeMs = now; + mPlatformIdleStateCallback.fillLowPowerStats(rpmStats); + synchronized (this) { + mTmpRpmStats = rpmStats; + mLastRpmStatsUpdateTimeMs = now; + } } + } + + /** + * Record Resource Power Manager (RPM) state and voter times. + * TODO(b/185252376): Remove this logging. PowerStatsService logs the same data more + * efficiently. + */ + public void updateRpmStatsLocked(long elapsedRealtimeUs) { + if (mTmpRpmStats == null) return; for (Map.Entry pstate : mTmpRpmStats.mPlatformLowPowerStats.entrySet()) { diff --git a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java index 406e8665735d1..67dfb8051f93c 100644 --- a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java +++ b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java @@ -579,6 +579,9 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { } } + // Collect the latest low power stats without holding the mStats lock. + mStats.fillLowPowerStats(); + final WifiActivityEnergyInfo wifiInfo = awaitControllerInfo(wifiReceiver); final BluetoothActivityEnergyInfo bluetoothInfo = awaitControllerInfo(bluetoothReceiver); ModemActivityInfo modemInfo = null;