Merge \"Add a new API to improve VR thread scheduling.\" into nyc-mr1-dev

am: 5e261441d3

Change-Id: Ie7c734ca22abad05a4f0800a1dba9553eb7cbfef
This commit is contained in:
Srinath Sridharan
2016-06-30 18:19:47 +00:00
committed by android-build-merger
9 changed files with 114 additions and 0 deletions

View File

@@ -3705,6 +3705,7 @@ package android.app {
method public void moveTaskToFront(int, int);
method public void moveTaskToFront(int, int, android.os.Bundle);
method public deprecated void restartPackage(java.lang.String);
method public static void setVrThread(int);
method public void setWatchHeapLimit(long);
field public static final java.lang.String ACTION_REPORT_HEAP_LIMIT = "android.app.action.REPORT_HEAP_LIMIT";
field public static final int LOCK_TASK_MODE_LOCKED = 1; // 0x1

View File

@@ -3841,6 +3841,7 @@ package android.app {
method public void moveTaskToFront(int, int);
method public void moveTaskToFront(int, int, android.os.Bundle);
method public deprecated void restartPackage(java.lang.String);
method public static void setVrThread(int);
method public void setWatchHeapLimit(long);
field public static final java.lang.String ACTION_REPORT_HEAP_LIMIT = "android.app.action.REPORT_HEAP_LIMIT";
field public static final int LOCK_TASK_MODE_LOCKED = 1; // 0x1

View File

@@ -3705,6 +3705,7 @@ package android.app {
method public void moveTaskToFront(int, int);
method public void moveTaskToFront(int, int, android.os.Bundle);
method public deprecated void restartPackage(java.lang.String);
method public static void setVrThread(int);
method public void setWatchHeapLimit(long);
field public static final java.lang.String ACTION_REPORT_HEAP_LIMIT = "android.app.action.REPORT_HEAP_LIMIT";
field public static final int LOCK_TASK_MODE_LOCKED = 1; // 0x1

View File

@@ -3624,6 +3624,24 @@ public class ActivityManager {
}
}
/**
* Enable more aggressive scheduling for latency-sensitive low-runtime VR threads. Only one
* thread can be a VR thread in a process at a time, and that thread may be subject to
* restrictions on the amount of time it can run.
*
* To reset the VR thread for an application, a tid of 0 can be passed.
*
* @see android.os.Process#myTid()
* @param tid tid of the VR thread
*/
public static void setVrThread(int tid) {
try {
ActivityManagerNative.getDefault().setVrThread(tid);
} catch (RemoteException e) {
// pass
}
}
/**
* The AppTask allows you to manage your own application's tasks.
* See {@link android.app.ActivityManager#getAppTasks()}

View File

@@ -2996,6 +2996,13 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
reply.writeInt(result);
return true;
}
case SET_VR_THREAD_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
final int tid = data.readInt();
setVrThread(tid);
reply.writeNoException();
return true;
}
}
return super.onTransact(code, data, reply, flags);
@@ -7031,5 +7038,19 @@ class ActivityManagerProxy implements IActivityManager
return res;
}
@Override
public void setVrThread(int tid)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeInt(tid);
mRemote.transact(SET_VR_THREAD_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
reply.recycle();
return;
}
private IBinder mRemote;
}

View File

@@ -658,6 +658,8 @@ public interface IActivityManager extends IInterface {
IIntentReceiver finishedReceiver, String requiredPermission, Bundle options)
throws RemoteException;
public void setVrThread(int tid) throws RemoteException;
/*
* Private non-Binder interfaces
*/
@@ -1044,4 +1046,5 @@ public interface IActivityManager extends IInterface {
int START_CONFIRM_DEVICE_CREDENTIAL_INTENT = IBinder.FIRST_CALL_TRANSACTION + 374;
int SEND_IDLE_JOB_TRIGGER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 375;
int SEND_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 376;
int SET_VR_THREAD_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 377;
}

View File

@@ -322,6 +322,13 @@ public class Process {
*/
public static final int SCHED_IDLE = 5;
/**
* Reset scheduler choice on fork.
* @hide
*/
public static final int SCHED_RESET_ON_FORK = 0x40000000;
// Keep in sync with SP_* constants of enum type SchedPolicy
// declared in system/core/include/cutils/sched_policy.h,
// except THREAD_GROUP_DEFAULT does not correspond to any SP_* value.

View File

@@ -2310,6 +2310,20 @@ public final class ActivityManagerService extends ActivityManagerNative
if (mInVrMode != vrMode) {
mInVrMode = vrMode;
mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
if (r.app != null) {
ProcessRecord proc = r.app;
if (proc.vrThreadTid > 0) {
if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
if (mInVrMode == true) {
Process.setThreadScheduler(proc.vrThreadTid,
Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
} else {
Process.setThreadScheduler(proc.vrThreadTid,
Process.SCHED_OTHER, 0);
}
}
}
}
}
}
vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
@@ -12508,6 +12522,34 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
public void setVrThread(int tid) {
if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
throw new UnsupportedOperationException("VR mode not supported on this device!");
}
synchronized (this) {
ProcessRecord proc;
synchronized (mPidsSelfLocked) {
final int pid = Binder.getCallingPid();
proc = mPidsSelfLocked.get(pid);
if (proc != null && mInVrMode && tid >= 0) {
// reset existing VR thread to CFS
if (proc.vrThreadTid != 0) {
Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
}
// add check to guarantee that tid belongs to pid?
proc.vrThreadTid = tid;
// promote to FIFO now if the tid is non-zero
if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP && proc.vrThreadTid > 0) {
Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
}
} else {
//Slog.e("VR_FIFO", "Didn't set thread from setVrThread?");
}
}
}
}
@Override
public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
@@ -20107,6 +20149,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
if (app.setSchedGroup != app.curSchedGroup) {
int oldSchedGroup = app.setSchedGroup;
app.setSchedGroup = app.curSchedGroup;
if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
"Setting sched group of " + app.processName
@@ -20132,6 +20175,23 @@ public final class ActivityManagerService extends ActivityManagerNative
long oldId = Binder.clearCallingIdentity();
try {
Process.setProcessGroup(app.pid, processGroup);
if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
// do nothing if we already switched to RT
if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
// Switch VR thread for app to SCHED_FIFO
if (mInVrMode && app.vrThreadTid != 0) {
Process.setThreadScheduler(app.vrThreadTid,
Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
}
}
} else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
// Reset VR thread to SCHED_OTHER
// Safe to do even if we're not in VR mode
if (app.vrThreadTid != 0) {
Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
}
}
} catch (Exception e) {
Slog.w(TAG, "Failed setting process group of " + app.pid
+ " to " + app.curSchedGroup);

View File

@@ -97,6 +97,7 @@ final class ProcessRecord {
int verifiedAdj; // The last adjustment that was verified as actually being set
int curSchedGroup; // Currently desired scheduling class
int setSchedGroup; // Last set to background scheduling class
int vrThreadTid; // Thread currently set for VR scheduling
int trimMemoryLevel; // Last selected memory trimming level
int curProcState = PROCESS_STATE_NONEXISTENT; // Currently computed process state
int repProcState = PROCESS_STATE_NONEXISTENT; // Last reported process state
@@ -293,6 +294,7 @@ final class ProcessRecord {
pw.print(" setSchedGroup="); pw.print(setSchedGroup);
pw.print(" systemNoUi="); pw.print(systemNoUi);
pw.print(" trimMemoryLevel="); pw.println(trimMemoryLevel);
pw.print(prefix); pw.print("vrThreadTid="); pw.print(vrThreadTid);
pw.print(prefix); pw.print("curProcState="); pw.print(curProcState);
pw.print(" repProcState="); pw.print(repProcState);
pw.print(" pssProcState="); pw.print(pssProcState);