Ease contention on the mProcessStatsThread mutex in updateCpuStats.
BUG=2606839
Change-Id: I444af0bb4a7b0be7ebf9ee5887805f2f09a426d0
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 13690bc..f8f8a0d 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -123,6 +123,8 @@
import java.util.Locale;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor {
static final String TAG = "ActivityManager";
@@ -927,7 +929,9 @@
*/
final ProcessStats mProcessStats = new ProcessStats(
MONITOR_THREAD_CPU_USAGE);
- long mLastCpuTime = 0;
+ final AtomicLong mLastCpuTime = new AtomicLong(0);
+ final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
+
long mLastWriteTime = 0;
long mInitialStartTime = 0;
@@ -1430,7 +1434,7 @@
try {
synchronized(this) {
final long now = SystemClock.uptimeMillis();
- long nextCpuDelay = (mLastCpuTime+MONITOR_CPU_MAX_TIME)-now;
+ long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
//Slog.i(TAG, "Cpu delay=" + nextCpuDelay
// + ", write delay=" + nextWriteDelay);
@@ -1438,12 +1442,12 @@
nextCpuDelay = nextWriteDelay;
}
if (nextCpuDelay > 0) {
+ mProcessStatsMutexFree.set(true);
this.wait(nextCpuDelay);
}
}
} catch (InterruptedException e) {
}
-
updateCpuStatsNow();
} catch (Exception e) {
Slog.e(TAG, "Unexpected exception collecting process stats", e);
@@ -1470,22 +1474,26 @@
}
void updateCpuStats() {
- synchronized (mProcessStatsThread) {
- final long now = SystemClock.uptimeMillis();
- if (mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) {
+ final long now = SystemClock.uptimeMillis();
+ if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
+ return;
+ }
+ if (mProcessStatsMutexFree.compareAndSet(true, false)) {
+ synchronized (mProcessStatsThread) {
mProcessStatsThread.notify();
}
}
}
-
+
void updateCpuStatsNow() {
synchronized (mProcessStatsThread) {
+ mProcessStatsMutexFree.set(false);
final long now = SystemClock.uptimeMillis();
boolean haveNewCpuStats = false;
if (MONITOR_CPU_USAGE &&
- mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) {
- mLastCpuTime = now;
+ mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
+ mLastCpuTime.set(now);
haveNewCpuStats = true;
mProcessStats.update();
//Slog.i(TAG, mProcessStats.printCurrentState());