Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 474d311c authored by Joel Fernandes's avatar Joel Fernandes
Browse files

Set android.display thread to top-app cpusets and schedtune group



android.display being in the foreground cpuset group is an issue. As
seen on M/S, during heavily CPU load it is not given core 3 even though
it might be free and causes jank. This patch adds the thread to the
top-app group to ensure it is placed on all cores during scheduling
decisions.

Doing this required a couple of changes:
- new API to set per-thread cpusets
- changes to DisplayManagerService to set the thread to top-app group
- changes to SystemServer to set the policy toward the end, as doing it
  during start of the DisplayManagerService was in issue (issue being
  SystemServer calls setSystemProcess.. -> setProcessGroup which overrides
  the group settings for threads in the system server process, including
  android.display)

Bug: 36631902
Test: Boot and make sure android.display thread is in the top-app group

Change-Id: Icc394ea0ffcf159d11728ad38de114234a29d20f
Signed-off-by: default avatarJoel Fernandes <joelaf@google.com>
parent 55ef06b2
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -675,6 +675,21 @@ public class Process {
    public static final native void setThreadGroup(int tid, int group)
            throws IllegalArgumentException, SecurityException;

    /**
     * Sets the scheduling group and the corresponding cpuset group
     * @hide
     * @param tid The identifier of the thread to change.
     * @param group The target group for this thread from THREAD_GROUP_*.
     *
     * @throws IllegalArgumentException Throws IllegalArgumentException if
     * <var>tid</var> does not exist.
     * @throws SecurityException Throws SecurityException if your process does
     * not have permission to modify the given thread, or to use the given
     * priority.
     */
    public static final native void setThreadGroupAndCpuset(int tid, int group)
            throws IllegalArgumentException, SecurityException;

    /**
     * Sets the scheduling group for a process and all child threads
     * @hide
+17 −0
Original line number Diff line number Diff line
@@ -176,6 +176,22 @@ void android_os_Process_setThreadGroup(JNIEnv* env, jobject clazz, int tid, jint
    }
}

void android_os_Process_setThreadGroupAndCpuset(JNIEnv* env, jobject clazz, int tid, jint grp)
{
    ALOGV("%s tid=%d grp=%" PRId32, __func__, tid, grp);
    SchedPolicy sp = (SchedPolicy) grp;
    int res = set_sched_policy(tid, sp);

    if (res != NO_ERROR) {
        signalExceptionForGroupError(env, -res, tid);
    }

    res = set_cpuset_policy(tid, sp);
    if (res != NO_ERROR) {
        signalExceptionForGroupError(env, -res, tid);
    }
}

void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jint grp)
{
    ALOGV("%s pid=%d grp=%" PRId32, __func__, pid, grp);
@@ -1207,6 +1223,7 @@ static const JNINativeMethod methods[] = {
    {"getThreadPriority",   "(I)I", (void*)android_os_Process_getThreadPriority},
    {"getThreadScheduler",   "(I)I", (void*)android_os_Process_getThreadScheduler},
    {"setThreadGroup",      "(II)V", (void*)android_os_Process_setThreadGroup},
    {"setThreadGroupAndCpuset", "(II)V", (void*)android_os_Process_setThreadGroupAndCpuset},
    {"setProcessGroup",     "(II)V", (void*)android_os_Process_setProcessGroup},
    {"getProcessGroup",     "(I)I", (void*)android_os_Process_getProcessGroup},
    {"getExclusiveCores",   "()[I", (void*)android_os_Process_getExclusiveCores},
+11 −0
Original line number Diff line number Diff line
@@ -253,6 +253,17 @@ public final class DisplayManagerService extends SystemService {

        PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
        mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting();

    }

    public void setupSchedulerPolicies() {
	/*
	 * android.display is critical to user experience and we should
	 * make sure it is not in the default foregroup groups, add it to
	 * top-app to make sure it uses all the cores and scheduling
	 * settings for top-app when it runs.
	 */
	Process.setThreadGroupAndCpuset(DisplayThread.get().getThreadId(), Process.THREAD_GROUP_TOP_APP);
    }

    @Override
+4 −0
Original line number Diff line number Diff line
@@ -614,6 +614,10 @@ public final class SystemServer {
        mActivityManagerService.setSystemProcess();
        traceEnd();

        // DisplayManagerService needs to setup android.display scheduling related policies
        // since setSystemProcess() would have overridden policies due to setProcessGroup
        mDisplayManagerService.setupSchedulerPolicies();

        // Manages Overlay packages
        traceBeginAndSlog("StartOverlayManagerService");
        mSystemServiceManager.startService(new OverlayManagerService(mSystemContext, installer));