Loading services/core/java/com/android/server/ThreadPriorityBooster.java +29 −9 Original line number Diff line number Diff line Loading @@ -16,14 +16,16 @@ package com.android.server; import android.os.Process; import static android.os.Process.getThreadPriority; import static android.os.Process.myTid; import static android.os.Process.setThreadPriority; /** * Utility class to boost threads in sections where important locks are held. */ public class ThreadPriorityBooster { private final int mBoostToPriority; private volatile int mBoostToPriority; private final int mLockGuardIndex; private final ThreadLocal<PriorityState> mThreadState = new ThreadLocal<PriorityState>() { Loading @@ -38,12 +40,12 @@ public class ThreadPriorityBooster { } public void boost() { final int tid = Process.myTid(); final int prevPriority = Process.getThreadPriority(tid); PriorityState state = mThreadState.get(); final int tid = myTid(); final int prevPriority = getThreadPriority(tid); final PriorityState state = mThreadState.get(); state.prevPriority = prevPriority; if (state.regionCounter == 0 && prevPriority > mBoostToPriority) { Process.setThreadPriority(tid, mBoostToPriority); setThreadPriority(tid, mBoostToPriority); } state.regionCounter++; if (LockGuard.ENABLED) { Loading @@ -52,10 +54,28 @@ public class ThreadPriorityBooster { } public void reset() { PriorityState state = mThreadState.get(); final PriorityState state = mThreadState.get(); state.regionCounter--; if (state.regionCounter == 0 && state.prevPriority > mBoostToPriority) { Process.setThreadPriority(Process.myTid(), state.prevPriority); final int currentPriority = getThreadPriority(myTid()); if (state.regionCounter == 0 && state.prevPriority != currentPriority) { setThreadPriority(myTid(), state.prevPriority); } } /** * Updates the priority we boost the threads to, and updates the current thread's priority if * necessary. */ protected void setBoostToPriority(int priority) { // We don't care about the other threads here, as long as they see the update of this // variable immediately. mBoostToPriority = priority; final PriorityState state = mThreadState.get(); final int tid = myTid(); final int prevPriority = getThreadPriority(tid); if (state.regionCounter != 0 && prevPriority != priority) { setThreadPriority(tid, priority); } } Loading services/core/java/com/android/server/am/ActivityManagerService.java +9 −3 Original line number Diff line number Diff line Loading @@ -453,6 +453,11 @@ import libcore.util.EmptyArray; public class ActivityManagerService extends IActivityManager.Stub implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { /** * Priority we boost main thread and RT of top app to. */ public static final int TOP_APP_PRIORITY_BOOST = -10; private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM; private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP; private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST; Loading Loading @@ -13426,7 +13431,7 @@ public class ActivityManagerService extends IActivityManager.Stub setThreadScheduler(proc.renderThreadTid, SCHED_FIFO | SCHED_RESET_ON_FORK, 1); } else { setThreadPriority(proc.renderThreadTid, -10); setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST); } } } else { Loading Loading @@ -21886,10 +21891,11 @@ public class ActivityManagerService extends IActivityManager.Stub } } else { // Boost priority for top app UI and render threads setThreadPriority(app.pid, -10); setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST); if (app.renderThreadTid != 0) { try { setThreadPriority(app.renderThreadTid, -10); setThreadPriority(app.renderThreadTid, TOP_APP_PRIORITY_BOOST); } catch (IllegalArgumentException e) { // thread died, ignore } services/core/java/com/android/server/wm/AppTransition.java +22 −5 Original line number Diff line number Diff line Loading @@ -313,6 +313,7 @@ public class AppTransition implements Dump { mNextAppTransition = transit; mNextAppTransitionFlags |= flags; setLastAppTransition(TRANSIT_UNSET, null, null); updateBooster(); } void setLastAppTransition(int transit, AppWindowToken openingApp, AppWindowToken closingApp) { Loading @@ -327,7 +328,7 @@ public class AppTransition implements Dump { } void setReady() { mAppTransitionState = APP_STATE_READY; setAppTransitionState(APP_STATE_READY); fetchAppTransitionSpecsFromFuture(); } Loading @@ -336,7 +337,7 @@ public class AppTransition implements Dump { } void setIdle() { mAppTransitionState = APP_STATE_IDLE; setAppTransitionState(APP_STATE_IDLE); } boolean isTimeout() { Loading @@ -344,7 +345,7 @@ public class AppTransition implements Dump { } void setTimeout() { mAppTransitionState = APP_STATE_TIMEOUT; setAppTransitionState(APP_STATE_TIMEOUT); } GraphicBuffer getAppTransitionThumbnailHeader(int taskId) { Loading Loading @@ -386,7 +387,7 @@ public class AppTransition implements Dump { private boolean prepare() { if (!isRunning()) { mAppTransitionState = APP_STATE_IDLE; setAppTransitionState(APP_STATE_IDLE); notifyAppTransitionPendingLocked(); mLastHadClipReveal = false; mLastClipRevealMaxTranslation = 0; Loading @@ -405,7 +406,7 @@ public class AppTransition implements Dump { ArraySet<AppWindowToken> closingApps) { mNextAppTransition = TRANSIT_UNSET; mNextAppTransitionFlags = 0; mAppTransitionState = APP_STATE_RUNNING; setAppTransitionState(APP_STATE_RUNNING); int redoLayout = notifyAppTransitionStartingLocked(transit, topOpeningAppAnimator != null ? topOpeningAppAnimator.mAppToken.token : null, topClosingAppAnimator != null ? topClosingAppAnimator.mAppToken.token : null, Loading Loading @@ -450,6 +451,22 @@ public class AppTransition implements Dump { notifyAppTransitionCancelledLocked(transit); } private void setAppTransitionState(int state) { mAppTransitionState = state; updateBooster(); } /** * Updates whether we currently boost wm locked sections and the animation thread. We want to * boost the priorities to a more important value whenever an app transition is going to happen * soon or an app transition is running. */ private void updateBooster() { WindowManagerService.sThreadPriorityBooster.setAppTransitionRunning( mNextAppTransition != TRANSIT_UNSET || mAppTransitionState == APP_STATE_READY || mAppTransitionState == APP_STATE_RUNNING); } void registerListenerLocked(AppTransitionListener listener) { mListeners.add(listener); } Loading services/core/java/com/android/server/wm/WindowManagerService.java +2 −2 Original line number Diff line number Diff line Loading @@ -870,8 +870,8 @@ public class WindowManagerService extends IWindowManager.Stub // since they won't be notified through the app window animator. final List<IBinder> mNoAnimationNotifyOnTransitionFinished = new ArrayList<>(); private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster( THREAD_PRIORITY_DISPLAY, INDEX_WINDOW); static WindowManagerThreadPriorityBooster sThreadPriorityBooster = new WindowManagerThreadPriorityBooster(); static void boostPriorityForLockedSection() { sThreadPriorityBooster.boost(); Loading services/core/java/com/android/server/wm/WindowManagerThreadPriorityBooster.java 0 → 100644 +78 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 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.os.Process.THREAD_PRIORITY_DISPLAY; import static android.os.Process.myTid; import static android.os.Process.setThreadPriority; import static com.android.server.LockGuard.INDEX_WINDOW; import static com.android.server.am.ActivityManagerService.TOP_APP_PRIORITY_BOOST; import com.android.server.AnimationThread; import com.android.server.ThreadPriorityBooster; /** * Window manager version of {@link ThreadPriorityBooster} that boosts even more during app * transitions. */ class WindowManagerThreadPriorityBooster extends ThreadPriorityBooster { private final AnimationThread mAnimationThread; private boolean mAppTransitionRunning; WindowManagerThreadPriorityBooster() { super(THREAD_PRIORITY_DISPLAY, INDEX_WINDOW); mAnimationThread = AnimationThread.get(); } @Override public void boost() { // Do not boost the animation thread. As the animation thread is changing priorities, // boosting it might mess up the priority because we reset it the the previous priority. if (myTid() == mAnimationThread.getThreadId()) { return; } super.boost(); } @Override public void reset() { // See comment in boost(). if (myTid() == mAnimationThread.getThreadId()) { return; } super.reset(); } void setAppTransitionRunning(boolean running) { if (mAppTransitionRunning == running) { return; } final int priority = calculatePriority(running); setBoostToPriority(priority); setThreadPriority(mAnimationThread.getThreadId(), priority); mAppTransitionRunning = running; } private int calculatePriority(boolean appTransitionRunning) { return appTransitionRunning ? TOP_APP_PRIORITY_BOOST : THREAD_PRIORITY_DISPLAY; } } Loading
services/core/java/com/android/server/ThreadPriorityBooster.java +29 −9 Original line number Diff line number Diff line Loading @@ -16,14 +16,16 @@ package com.android.server; import android.os.Process; import static android.os.Process.getThreadPriority; import static android.os.Process.myTid; import static android.os.Process.setThreadPriority; /** * Utility class to boost threads in sections where important locks are held. */ public class ThreadPriorityBooster { private final int mBoostToPriority; private volatile int mBoostToPriority; private final int mLockGuardIndex; private final ThreadLocal<PriorityState> mThreadState = new ThreadLocal<PriorityState>() { Loading @@ -38,12 +40,12 @@ public class ThreadPriorityBooster { } public void boost() { final int tid = Process.myTid(); final int prevPriority = Process.getThreadPriority(tid); PriorityState state = mThreadState.get(); final int tid = myTid(); final int prevPriority = getThreadPriority(tid); final PriorityState state = mThreadState.get(); state.prevPriority = prevPriority; if (state.regionCounter == 0 && prevPriority > mBoostToPriority) { Process.setThreadPriority(tid, mBoostToPriority); setThreadPriority(tid, mBoostToPriority); } state.regionCounter++; if (LockGuard.ENABLED) { Loading @@ -52,10 +54,28 @@ public class ThreadPriorityBooster { } public void reset() { PriorityState state = mThreadState.get(); final PriorityState state = mThreadState.get(); state.regionCounter--; if (state.regionCounter == 0 && state.prevPriority > mBoostToPriority) { Process.setThreadPriority(Process.myTid(), state.prevPriority); final int currentPriority = getThreadPriority(myTid()); if (state.regionCounter == 0 && state.prevPriority != currentPriority) { setThreadPriority(myTid(), state.prevPriority); } } /** * Updates the priority we boost the threads to, and updates the current thread's priority if * necessary. */ protected void setBoostToPriority(int priority) { // We don't care about the other threads here, as long as they see the update of this // variable immediately. mBoostToPriority = priority; final PriorityState state = mThreadState.get(); final int tid = myTid(); final int prevPriority = getThreadPriority(tid); if (state.regionCounter != 0 && prevPriority != priority) { setThreadPriority(tid, priority); } } Loading
services/core/java/com/android/server/am/ActivityManagerService.java +9 −3 Original line number Diff line number Diff line Loading @@ -453,6 +453,11 @@ import libcore.util.EmptyArray; public class ActivityManagerService extends IActivityManager.Stub implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { /** * Priority we boost main thread and RT of top app to. */ public static final int TOP_APP_PRIORITY_BOOST = -10; private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM; private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP; private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST; Loading Loading @@ -13426,7 +13431,7 @@ public class ActivityManagerService extends IActivityManager.Stub setThreadScheduler(proc.renderThreadTid, SCHED_FIFO | SCHED_RESET_ON_FORK, 1); } else { setThreadPriority(proc.renderThreadTid, -10); setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST); } } } else { Loading Loading @@ -21886,10 +21891,11 @@ public class ActivityManagerService extends IActivityManager.Stub } } else { // Boost priority for top app UI and render threads setThreadPriority(app.pid, -10); setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST); if (app.renderThreadTid != 0) { try { setThreadPriority(app.renderThreadTid, -10); setThreadPriority(app.renderThreadTid, TOP_APP_PRIORITY_BOOST); } catch (IllegalArgumentException e) { // thread died, ignore }
services/core/java/com/android/server/wm/AppTransition.java +22 −5 Original line number Diff line number Diff line Loading @@ -313,6 +313,7 @@ public class AppTransition implements Dump { mNextAppTransition = transit; mNextAppTransitionFlags |= flags; setLastAppTransition(TRANSIT_UNSET, null, null); updateBooster(); } void setLastAppTransition(int transit, AppWindowToken openingApp, AppWindowToken closingApp) { Loading @@ -327,7 +328,7 @@ public class AppTransition implements Dump { } void setReady() { mAppTransitionState = APP_STATE_READY; setAppTransitionState(APP_STATE_READY); fetchAppTransitionSpecsFromFuture(); } Loading @@ -336,7 +337,7 @@ public class AppTransition implements Dump { } void setIdle() { mAppTransitionState = APP_STATE_IDLE; setAppTransitionState(APP_STATE_IDLE); } boolean isTimeout() { Loading @@ -344,7 +345,7 @@ public class AppTransition implements Dump { } void setTimeout() { mAppTransitionState = APP_STATE_TIMEOUT; setAppTransitionState(APP_STATE_TIMEOUT); } GraphicBuffer getAppTransitionThumbnailHeader(int taskId) { Loading Loading @@ -386,7 +387,7 @@ public class AppTransition implements Dump { private boolean prepare() { if (!isRunning()) { mAppTransitionState = APP_STATE_IDLE; setAppTransitionState(APP_STATE_IDLE); notifyAppTransitionPendingLocked(); mLastHadClipReveal = false; mLastClipRevealMaxTranslation = 0; Loading @@ -405,7 +406,7 @@ public class AppTransition implements Dump { ArraySet<AppWindowToken> closingApps) { mNextAppTransition = TRANSIT_UNSET; mNextAppTransitionFlags = 0; mAppTransitionState = APP_STATE_RUNNING; setAppTransitionState(APP_STATE_RUNNING); int redoLayout = notifyAppTransitionStartingLocked(transit, topOpeningAppAnimator != null ? topOpeningAppAnimator.mAppToken.token : null, topClosingAppAnimator != null ? topClosingAppAnimator.mAppToken.token : null, Loading Loading @@ -450,6 +451,22 @@ public class AppTransition implements Dump { notifyAppTransitionCancelledLocked(transit); } private void setAppTransitionState(int state) { mAppTransitionState = state; updateBooster(); } /** * Updates whether we currently boost wm locked sections and the animation thread. We want to * boost the priorities to a more important value whenever an app transition is going to happen * soon or an app transition is running. */ private void updateBooster() { WindowManagerService.sThreadPriorityBooster.setAppTransitionRunning( mNextAppTransition != TRANSIT_UNSET || mAppTransitionState == APP_STATE_READY || mAppTransitionState == APP_STATE_RUNNING); } void registerListenerLocked(AppTransitionListener listener) { mListeners.add(listener); } Loading
services/core/java/com/android/server/wm/WindowManagerService.java +2 −2 Original line number Diff line number Diff line Loading @@ -870,8 +870,8 @@ public class WindowManagerService extends IWindowManager.Stub // since they won't be notified through the app window animator. final List<IBinder> mNoAnimationNotifyOnTransitionFinished = new ArrayList<>(); private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster( THREAD_PRIORITY_DISPLAY, INDEX_WINDOW); static WindowManagerThreadPriorityBooster sThreadPriorityBooster = new WindowManagerThreadPriorityBooster(); static void boostPriorityForLockedSection() { sThreadPriorityBooster.boost(); Loading
services/core/java/com/android/server/wm/WindowManagerThreadPriorityBooster.java 0 → 100644 +78 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 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.os.Process.THREAD_PRIORITY_DISPLAY; import static android.os.Process.myTid; import static android.os.Process.setThreadPriority; import static com.android.server.LockGuard.INDEX_WINDOW; import static com.android.server.am.ActivityManagerService.TOP_APP_PRIORITY_BOOST; import com.android.server.AnimationThread; import com.android.server.ThreadPriorityBooster; /** * Window manager version of {@link ThreadPriorityBooster} that boosts even more during app * transitions. */ class WindowManagerThreadPriorityBooster extends ThreadPriorityBooster { private final AnimationThread mAnimationThread; private boolean mAppTransitionRunning; WindowManagerThreadPriorityBooster() { super(THREAD_PRIORITY_DISPLAY, INDEX_WINDOW); mAnimationThread = AnimationThread.get(); } @Override public void boost() { // Do not boost the animation thread. As the animation thread is changing priorities, // boosting it might mess up the priority because we reset it the the previous priority. if (myTid() == mAnimationThread.getThreadId()) { return; } super.boost(); } @Override public void reset() { // See comment in boost(). if (myTid() == mAnimationThread.getThreadId()) { return; } super.reset(); } void setAppTransitionRunning(boolean running) { if (mAppTransitionRunning == running) { return; } final int priority = calculatePriority(running); setBoostToPriority(priority); setThreadPriority(mAnimationThread.getThreadId(), priority); mAppTransitionRunning = running; } private int calculatePriority(boolean appTransitionRunning) { return appTransitionRunning ? TOP_APP_PRIORITY_BOOST : THREAD_PRIORITY_DISPLAY; } }