Activity Manager changes the scheduling group of processes.
The algorithm for this is currently very simple: all persistent processes are always in the normal scheduling group, all other processes are normal if their oom_adj is as good or better than VISIBLE, otherwise they are in the background group. Note that this currently results in a fair number of log messages about not being able to change the group, since the system process does not have permission to do so. Once a kernel fix is in, these will go away and the code will start working.
This commit is contained in:
@@ -1513,6 +1513,18 @@ public final class ActivityThread {
|
||||
queueOrSendMessage(H.PROFILER_CONTROL, path, start ? 1 : 0);
|
||||
}
|
||||
|
||||
public void setSchedulingGroup(int group) {
|
||||
// Note: do this immediately, since going into the foreground
|
||||
// should happen regardless of what pending work we have to do
|
||||
// and the activity manager will wait for us to report back that
|
||||
// we are done before sending us to the background.
|
||||
try {
|
||||
Process.setProcessGroup(Process.myPid(), group);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Failed setting process group to " + group, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||
long nativeMax = Debug.getNativeHeapSize() / 1024;
|
||||
|
||||
@@ -331,6 +331,14 @@ public abstract class ApplicationThreadNative extends Binder
|
||||
profilerControl(start, path);
|
||||
return true;
|
||||
}
|
||||
|
||||
case SET_SCHEDULING_GROUP_TRANSACTION:
|
||||
{
|
||||
data.enforceInterface(IApplicationThread.descriptor);
|
||||
int group = data.readInt();
|
||||
setSchedulingGroup(group);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return super.onTransact(code, data, reply, flags);
|
||||
@@ -672,5 +680,14 @@ class ApplicationThreadProxy implements IApplicationThread {
|
||||
IBinder.FLAG_ONEWAY);
|
||||
data.recycle();
|
||||
}
|
||||
|
||||
public void setSchedulingGroup(int group) throws RemoteException {
|
||||
Parcel data = Parcel.obtain();
|
||||
data.writeInterfaceToken(IApplicationThread.descriptor);
|
||||
data.writeInt(group);
|
||||
mRemote.transact(SET_SCHEDULING_GROUP_TRANSACTION, data, null,
|
||||
IBinder.FLAG_ONEWAY);
|
||||
data.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,8 @@ public interface IApplicationThread extends IInterface {
|
||||
void scheduleActivityConfigurationChanged(IBinder token) throws RemoteException;
|
||||
void requestPss() throws RemoteException;
|
||||
void profilerControl(boolean start, String path) throws RemoteException;
|
||||
|
||||
void setSchedulingGroup(int group) throws RemoteException;
|
||||
|
||||
String descriptor = "android.app.IApplicationThread";
|
||||
|
||||
int SCHEDULE_PAUSE_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION;
|
||||
@@ -117,4 +118,5 @@ public interface IApplicationThread extends IInterface {
|
||||
int SCHEDULE_RELAUNCH_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+25;
|
||||
int REQUEST_PSS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+26;
|
||||
int PROFILER_CONTROL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+27;
|
||||
int SET_SCHEDULING_GROUP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+28;
|
||||
}
|
||||
|
||||
@@ -4733,6 +4733,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
||||
|
||||
app.thread = thread;
|
||||
app.curAdj = app.setAdj = -100;
|
||||
app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
|
||||
app.forcingToForeground = null;
|
||||
app.foregroundServices = false;
|
||||
app.debugging = false;
|
||||
@@ -8802,9 +8803,9 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
||||
+ " #" + i + ":");
|
||||
r.dump(pw, prefix + " ");
|
||||
} else if (inclOomAdj) {
|
||||
pw.println(String.format("%s%s #%2d: oom_adj=%3d %s",
|
||||
pw.println(String.format("%s%s #%2d: adj=%3d/%d %s",
|
||||
prefix, (r.persistent ? persistentLabel : normalLabel),
|
||||
i, r.setAdj, r.toString()));
|
||||
i, r.setAdj, r.setSchedGroup, r.toString()));
|
||||
} else {
|
||||
pw.println(String.format("%s%s #%2d: %s",
|
||||
prefix, (r.persistent ? persistentLabel : normalLabel),
|
||||
@@ -11830,7 +11831,10 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
||||
}
|
||||
|
||||
app.curAdj = adj;
|
||||
|
||||
app.curSchedGroup = (adj > VISIBLE_APP_ADJ && !app.persistent)
|
||||
? Process.THREAD_GROUP_BG_NONINTERACTIVE
|
||||
: Process.THREAD_GROUP_DEFAULT;
|
||||
|
||||
return adj;
|
||||
}
|
||||
|
||||
@@ -11975,6 +11979,28 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (app.setSchedGroup != app.curSchedGroup) {
|
||||
app.setSchedGroup = app.curSchedGroup;
|
||||
if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v(TAG,
|
||||
"Setting process group of " + app.processName
|
||||
+ " to " + app.curSchedGroup);
|
||||
if (true) {
|
||||
try {
|
||||
Process.setProcessGroup(app.pid, app.curSchedGroup);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Failed setting process group of " + app.pid
|
||||
+ " to " + app.curSchedGroup);
|
||||
}
|
||||
}
|
||||
if (false) {
|
||||
if (app.thread != null) {
|
||||
try {
|
||||
app.thread.setSchedulingGroup(app.curSchedGroup);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -56,6 +56,8 @@ class ProcessRecord implements Watchdog.PssRequestor {
|
||||
int setRawAdj; // Last set OOM unlimited adjustment for this process
|
||||
int curAdj; // Current OOM adjustment for this process
|
||||
int setAdj; // Last set OOM adjustment for this process
|
||||
int curSchedGroup; // Currently desired scheduling class
|
||||
int setSchedGroup; // Last set to background scheduling class
|
||||
boolean isForeground; // Is this app running the foreground UI?
|
||||
boolean setIsForeground; // Running foreground UI when last set?
|
||||
boolean foregroundServices; // Running any services that are foreground?
|
||||
@@ -147,6 +149,8 @@ class ProcessRecord implements Watchdog.PssRequestor {
|
||||
pw.print(" setRaw="); pw.print(setRawAdj);
|
||||
pw.print(" cur="); pw.print(curAdj);
|
||||
pw.print(" set="); pw.println(setAdj);
|
||||
pw.print(prefix); pw.print("curSchedGroup="); pw.print(curSchedGroup);
|
||||
pw.print(" setSchedGroup="); pw.println(setSchedGroup);
|
||||
pw.print(prefix); pw.print("isForeground="); pw.print(isForeground);
|
||||
pw.print(" setIsForeground="); pw.print(setIsForeground);
|
||||
pw.print(" foregroundServices="); pw.print(foregroundServices);
|
||||
|
||||
Reference in New Issue
Block a user