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

Commit 98e23164 authored by Rick Yiu's avatar Rick Yiu
Browse files

Use async approach to change sched policy

Currently, sched policy of a thread may be changed when setting
its priority. However, the sched policy change may fail because
of the limitation of sepolicy. To solve it, use async approach
to let activity manager service change the sched policy of the
thread.

Bug: 139521784
Test: function works as expected
Change-Id: I967723e8f7ad95c76fd7efdc952d6f7b579b1d61
parent 519840df
Loading
Loading
Loading
Loading
+47 −5
Original line number Original line Diff line number Diff line
@@ -19,16 +19,18 @@


// To make sure cpu_set_t is included from sched.h
// To make sure cpu_set_t is included from sched.h
#define _GNU_SOURCE 1
#define _GNU_SOURCE 1
#include <utils/Log.h>
#include <android-base/properties.h>
#include <android-base/unique_fd.h>
#include <binder/ActivityManager.h>
#include <binder/IPCThreadState.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/IServiceManager.h>
#include <utils/String8.h>
#include <utils/Vector.h>
#include <meminfo/procmeminfo.h>
#include <meminfo/procmeminfo.h>
#include <meminfo/sysmeminfo.h>
#include <meminfo/sysmeminfo.h>
#include <processgroup/processgroup.h>
#include <processgroup/processgroup.h>
#include <processgroup/sched_policy.h>
#include <processgroup/sched_policy.h>
#include <android-base/unique_fd.h>
#include <utils/Log.h>
#include <utils/String8.h>
#include <utils/Vector.h>


#include <algorithm>
#include <algorithm>
#include <array>
#include <array>
@@ -84,6 +86,8 @@ Mutex gKeyCreateMutex;
static pthread_key_t gBgKey = -1;
static pthread_key_t gBgKey = -1;
#endif
#endif


static bool boot_completed = false;

// For both of these, err should be in the errno range (positive), not a status_t (negative)
// For both of these, err should be in the errno range (positive), not a status_t (negative)
static void signalExceptionForError(JNIEnv* env, int err, int tid) {
static void signalExceptionForError(JNIEnv* env, int err, int tid) {
    switch (err) {
    switch (err) {
@@ -574,7 +578,20 @@ void android_os_Process_setThreadPriority(JNIEnv* env, jobject clazz,
    }
    }
#endif
#endif


    int rc = androidSetThreadPriority(pid, pri);
    SchedPolicy policy;
    bool policy_changed = false;
    int rc = 0, curr_pri = getpriority(PRIO_PROCESS, pid);

    if (pri == curr_pri) {
        return;
    }

    if (!boot_completed) {
        boot_completed = android::base::GetBoolProperty("sys.boot_completed", false);
    }

    // Do not change sched policy cgroup after boot complete.
    rc = androidSetThreadPriority(pid, pri, !boot_completed);
    if (rc != 0) {
    if (rc != 0) {
        if (rc == INVALID_OPERATION) {
        if (rc == INVALID_OPERATION) {
            signalExceptionForPriorityError(env, errno, pid);
            signalExceptionForPriorityError(env, errno, pid);
@@ -583,6 +600,31 @@ void android_os_Process_setThreadPriority(JNIEnv* env, jobject clazz,
        }
        }
    }
    }


    // Only use async approach after boot complete.
    if (!boot_completed) {
        return;
    }

    // Change to background sched policy for the thread if setting to low priority.
    if (pri >= ANDROID_PRIORITY_BACKGROUND) {
        policy = SP_BACKGROUND;
        policy_changed = true;
        // Change to sched policy of the process if thread priority is raising from low priority.
    } else if (curr_pri >= ANDROID_PRIORITY_BACKGROUND) {
        // If we cannot get sched policy of the process, use SP_FOREGROUND as default.
        policy = SP_FOREGROUND;
        get_sched_policy(getpid(), &policy);
        policy_changed = true;
    }

    // Sched policy will only change in above 2 cases.
    if (policy_changed) {
        ActivityManager am;
        if (!am.setSchedPolicyCgroup(pid, policy)) {
            ALOGE("am.setThreadPriority failed: tid=%d priority=%d policy=%d", pid, pri, policy);
        }
    }

    //ALOGI("Setting priority of %" PRId32 ": %" PRId32 ", getpriority returns %d\n",
    //ALOGI("Setting priority of %" PRId32 ": %" PRId32 ", getpriority returns %d\n",
    //     pid, pri, getpriority(PRIO_PROCESS, pid));
    //     pid, pri, getpriority(PRIO_PROCESS, pid));
}
}