Merge "Boost android.anim and wm lock sections to -10 during transition" into oc-dev

am: 713ad88afe

Change-Id: Ie76d079092805920ebd6820ce412691ccdceb039
This commit is contained in:
Jorim Jaggi
2017-06-09 04:11:31 +00:00
committed by android-build-merger
5 changed files with 140 additions and 19 deletions

View File

@@ -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>() {
@@ -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) {
@@ -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);
}
}

View File

@@ -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;
@@ -13489,7 +13494,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 {
@@ -21949,10 +21954,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
}

View File

@@ -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) {
@@ -327,7 +328,7 @@ public class AppTransition implements Dump {
}
void setReady() {
mAppTransitionState = APP_STATE_READY;
setAppTransitionState(APP_STATE_READY);
fetchAppTransitionSpecsFromFuture();
}
@@ -336,7 +337,7 @@ public class AppTransition implements Dump {
}
void setIdle() {
mAppTransitionState = APP_STATE_IDLE;
setAppTransitionState(APP_STATE_IDLE);
}
boolean isTimeout() {
@@ -344,7 +345,7 @@ public class AppTransition implements Dump {
}
void setTimeout() {
mAppTransitionState = APP_STATE_TIMEOUT;
setAppTransitionState(APP_STATE_TIMEOUT);
}
GraphicBuffer getAppTransitionThumbnailHeader(int taskId) {
@@ -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;
@@ -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,
@@ -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);
}

View File

@@ -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();

View File

@@ -0,0 +1,78 @@
/*
* 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;
}
}