Add annotation to the performance sensitive methods
So we can evaluate more easily later if something can be optimized.
Also:
- Make ActiveUids a separated lock to reduce locking WM.
- Use more lock-without-boost for the methods that are already
in another priority booster.
Bug: 122505787
Test: Boot device
Change-Id: I2e942b1f0b888e155f622ddbc850a481c0c88578
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index d40948b..bba2299 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -936,7 +936,7 @@
return false;
}
// don't abort if the callingUid is in the foreground or is a persistent system process
- final int callingUidProcState = mService.getUidStateLocked(callingUid);
+ final int callingUidProcState = mService.getUidState(callingUid);
final boolean callingUidHasAnyVisibleWindow =
mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(callingUid);
final boolean isCallingUidForeground = callingUidHasAnyVisibleWindow
@@ -949,7 +949,7 @@
// take realCallingUid into consideration
final int realCallingUidProcState = (callingUid == realCallingUid)
? callingUidProcState
- : mService.getUidStateLocked(realCallingUid);
+ : mService.getUidState(realCallingUid);
final boolean realCallingUidHasAnyVisibleWindow = (callingUid == realCallingUid)
? callingUidHasAnyVisibleWindow
: mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(realCallingUid);
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 258819f..e742df5 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -26,7 +26,6 @@
import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
import static android.Manifest.permission.STOP_APP_SWITCHES;
import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
-import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW;
@@ -272,6 +271,10 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
import java.lang.ref.WeakReference;
import java.text.DateFormat;
import java.util.ArrayList;
@@ -363,7 +366,7 @@
private UserManagerService mUserManager;
private AppOpsService mAppOpsService;
/** All active uids in the system. */
- private final SparseArray<Integer> mActiveUids = new SparseArray<>();
+ private final MirrorActiveUids mActiveUids = new MirrorActiveUids();
private final SparseArray<String> mPendingTempWhitelist = new SparseArray<>();
/** All processes currently running that might have a window organized by name. */
final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>();
@@ -647,6 +650,17 @@
}
}
+ /** Indicates that the method may be invoked frequently or is sensitive to performance. */
+ @Target(ElementType.METHOD)
+ @Retention(RetentionPolicy.SOURCE)
+ @interface HotPath {
+ int NONE = 0;
+ int OOM_ADJUSTMENT = 1;
+ int LRU_UPDATE = 2;
+ int PROCESS_CHANGE = 3;
+ int caller() default NONE;
+ }
+
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public ActivityTaskManagerService(Context context) {
mContext = context;
@@ -5709,12 +5723,12 @@
return null;
}
- int getUidStateLocked(int uid) {
- return mActiveUids.get(uid, PROCESS_STATE_NONEXISTENT);
+ int getUidState(int uid) {
+ return mActiveUids.getUidState(uid);
}
boolean isUidForeground(int uid) {
- return (getUidStateLocked(uid) == ActivityManager.PROCESS_STATE_TOP)
+ return (getUidState(uid) == ActivityManager.PROCESS_STATE_TOP)
|| mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(uid);
}
@@ -6109,23 +6123,26 @@
}
}
+ @HotPath(caller = HotPath.PROCESS_CHANGE)
@Override
public void onProcessAdded(WindowProcessController proc) {
- synchronized (mGlobalLock) {
+ synchronized (mGlobalLockWithoutBoost) {
mProcessNames.put(proc.mName, proc.mUid, proc);
}
}
+ @HotPath(caller = HotPath.PROCESS_CHANGE)
@Override
public void onProcessRemoved(String name, int uid) {
- synchronized (mGlobalLock) {
+ synchronized (mGlobalLockWithoutBoost) {
mProcessNames.remove(name, uid);
}
}
+ @HotPath(caller = HotPath.PROCESS_CHANGE)
@Override
public void onCleanUpApplicationRecord(WindowProcessController proc) {
- synchronized (mGlobalLock) {
+ synchronized (mGlobalLockWithoutBoost) {
if (proc == mHomeProcess) {
mHomeProcess = null;
}
@@ -6135,23 +6152,26 @@
}
}
+ @HotPath(caller = HotPath.OOM_ADJUSTMENT)
@Override
public int getTopProcessState() {
- synchronized (mGlobalLock) {
+ synchronized (mGlobalLockWithoutBoost) {
return mTopProcessState;
}
}
+ @HotPath(caller = HotPath.OOM_ADJUSTMENT)
@Override
public boolean isHeavyWeightProcess(WindowProcessController proc) {
- synchronized (mGlobalLock) {
+ synchronized (mGlobalLockWithoutBoost) {
return proc == mHeavyWeightProcess;
}
}
+ @HotPath(caller = HotPath.PROCESS_CHANGE)
@Override
public void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
- synchronized (mGlobalLock) {
+ synchronized (mGlobalLockWithoutBoost) {
ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(proc);
}
}
@@ -6167,9 +6187,10 @@
}
}
+ @HotPath(caller = HotPath.OOM_ADJUSTMENT)
@Override
public boolean isSleeping() {
- synchronized (mGlobalLock) {
+ synchronized (mGlobalLockWithoutBoost) {
return isSleepingLocked();
}
}
@@ -6413,9 +6434,10 @@
}
}
+ @HotPath(caller = HotPath.PROCESS_CHANGE)
@Override
public boolean isFactoryTestProcess(WindowProcessController wpc) {
- synchronized (mGlobalLock) {
+ synchronized (mGlobalLockWithoutBoost) {
if (mFactoryTest == FACTORY_TEST_OFF) {
return false;
}
@@ -6468,10 +6490,11 @@
}
}
+ @HotPath(caller = HotPath.PROCESS_CHANGE)
@Override
public void handleAppDied(WindowProcessController wpc, boolean restarting,
Runnable finishInstrumentationCallback) {
- synchronized (mGlobalLock) {
+ synchronized (mGlobalLockWithoutBoost) {
// Remove this application's activities from active lists.
boolean hasVisibleActivities = mRootActivityContainer.handleAppDied(wpc);
@@ -6570,16 +6593,18 @@
}
}
+ @HotPath(caller = HotPath.PROCESS_CHANGE)
@Override
public void preBindApplication(WindowProcessController wpc) {
- synchronized (mGlobalLock) {
+ synchronized (mGlobalLockWithoutBoost) {
mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(wpc.mInfo);
}
}
+ @HotPath(caller = HotPath.PROCESS_CHANGE)
@Override
public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
- synchronized (mGlobalLock) {
+ synchronized (mGlobalLockWithoutBoost) {
return mRootActivityContainer.attachApplication(wpc);
}
}
@@ -6907,6 +6932,7 @@
}
}
+ @HotPath(caller = HotPath.OOM_ADJUSTMENT)
@Override
public WindowProcessController getTopApp() {
synchronized (mGlobalLockWithoutBoost) {
@@ -6915,6 +6941,7 @@
}
}
+ @HotPath(caller = HotPath.OOM_ADJUSTMENT)
@Override
public void rankTaskLayersIfNeeded() {
synchronized (mGlobalLockWithoutBoost) {
@@ -6959,34 +6986,28 @@
}
}
+ @HotPath(caller = HotPath.OOM_ADJUSTMENT)
@Override
public void onUidActive(int uid, int procState) {
- synchronized (mGlobalLockWithoutBoost) {
- mActiveUids.put(uid, procState);
- }
+ mActiveUids.onUidActive(uid, procState);
}
+ @HotPath(caller = HotPath.OOM_ADJUSTMENT)
@Override
public void onUidInactive(int uid) {
- synchronized (mGlobalLockWithoutBoost) {
- mActiveUids.remove(uid);
- }
+ mActiveUids.onUidInactive(uid);
}
+ @HotPath(caller = HotPath.OOM_ADJUSTMENT)
@Override
public void onActiveUidsCleared() {
- synchronized (mGlobalLockWithoutBoost) {
- mActiveUids.clear();
- }
+ mActiveUids.onActiveUidsCleared();
}
+ @HotPath(caller = HotPath.OOM_ADJUSTMENT)
@Override
public void onUidProcStateChanged(int uid, int procState) {
- synchronized (mGlobalLockWithoutBoost) {
- if (mActiveUids.get(uid) != null) {
- mActiveUids.put(uid, procState);
- }
- }
+ mActiveUids.onUidProcStateChanged(uid, procState);
}
@Override
diff --git a/services/core/java/com/android/server/wm/MirrorActiveUids.java b/services/core/java/com/android/server/wm/MirrorActiveUids.java
new file mode 100644
index 0000000..0047942
--- /dev/null
+++ b/services/core/java/com/android/server/wm/MirrorActiveUids.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
+
+import android.util.SparseIntArray;
+
+/**
+ * This is a partial mirror of {@link @com.android.server.am.ActiveUids}. It is already thread
+ * safe so the heavy service lock is not needed when updating state from activity manager (oom
+ * adjustment) or getting state from window manager (background start check).
+ */
+class MirrorActiveUids {
+ private SparseIntArray mUidStates = new SparseIntArray();
+
+ synchronized void onUidActive(int uid, int procState) {
+ mUidStates.put(uid, procState);
+ }
+
+ synchronized void onUidInactive(int uid) {
+ mUidStates.delete(uid);
+ }
+
+ synchronized void onActiveUidsCleared() {
+ mUidStates.clear();
+ }
+
+ synchronized void onUidProcStateChanged(int uid, int procState) {
+ final int index = mUidStates.indexOfKey(uid);
+ if (index >= 0) {
+ mUidStates.setValueAt(index, procState);
+ }
+ }
+
+ synchronized int getUidState(int uid) {
+ return mUidStates.get(uid, PROCESS_STATE_NONEXISTENT);
+ }
+}
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 465f413..dceed28 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -57,6 +57,7 @@
import com.android.internal.app.HeavyWeightSwitcherActivity;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.Watchdog;
+import com.android.server.wm.ActivityTaskManagerService.HotPath;
import java.io.IOException;
import java.io.PrintWriter;
@@ -408,12 +409,14 @@
return null;
}
+ @HotPath(caller = HotPath.PROCESS_CHANGE)
public void addPackage(String packageName) {
synchronized (mAtm.mGlobalLockWithoutBoost) {
mPkgList.add(packageName);
}
}
+ @HotPath(caller = HotPath.PROCESS_CHANGE)
public void clearPackageList() {
synchronized (mAtm.mGlobalLockWithoutBoost) {
mPkgList.clear();
@@ -441,12 +444,14 @@
mActivities.clear();
}
+ @HotPath(caller = HotPath.OOM_ADJUSTMENT)
public boolean hasActivities() {
synchronized (mAtm.mGlobalLockWithoutBoost) {
return !mActivities.isEmpty();
}
}
+ @HotPath(caller = HotPath.OOM_ADJUSTMENT)
public boolean hasVisibleActivities() {
synchronized (mAtm.mGlobalLockWithoutBoost) {
for (int i = mActivities.size() - 1; i >= 0; --i) {
@@ -459,6 +464,7 @@
return false;
}
+ @HotPath(caller = HotPath.LRU_UPDATE)
public boolean hasActivitiesOrRecentTasks() {
synchronized (mAtm.mGlobalLockWithoutBoost) {
return !mActivities.isEmpty() || !mRecentTasks.isEmpty();
@@ -670,6 +676,7 @@
void onOtherActivity();
}
+ @HotPath(caller = HotPath.OOM_ADJUSTMENT)
public int computeOomAdjFromActivities(int minTaskLayer, ComputeOomAdjCallback callback) {
synchronized (mAtm.mGlobalLockWithoutBoost) {
final int activitiesSize = mActivities.size();
@@ -903,6 +910,7 @@
mRecentTasks.remove(task);
}
+ @HotPath(caller = HotPath.OOM_ADJUSTMENT)
public boolean hasRecentTasks() {
synchronized (mAtm.mGlobalLockWithoutBoost) {
return !mRecentTasks.isEmpty();
@@ -966,18 +974,21 @@
return false;
}
+ @HotPath(caller = HotPath.OOM_ADJUSTMENT)
public void onTopProcChanged() {
synchronized (mAtm.mGlobalLockWithoutBoost) {
mAtm.mVrController.onTopProcChangedLocked(this);
}
}
+ @HotPath(caller = HotPath.OOM_ADJUSTMENT)
public boolean isHomeProcess() {
synchronized (mAtm.mGlobalLockWithoutBoost) {
return this == mAtm.mHomeProcess;
}
}
+ @HotPath(caller = HotPath.OOM_ADJUSTMENT)
public boolean isPreviousProcess() {
synchronized (mAtm.mGlobalLockWithoutBoost) {
return this == mAtm.mPreviousProcess;