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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user