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

Commit a79ed390 authored by Christopher Tate's avatar Christopher Tate
Browse files

DO NOT MERGE - backport Eclair binder thread pool scheduling policy

parent 36904b29
Loading
Loading
Loading
Loading
+38 −42
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include <sys/errno.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <cutils/sched_policy.h>
#include <dirent.h>
#include <fcntl.h>
#include <grp.h>
@@ -50,13 +51,7 @@ pid_t gettid() { return syscall(__NR_gettid);}
#undef __KERNEL__
#endif

/*
 * List of cgroup names which map to ANDROID_TGROUP_ values in Thread.h
 * and Process.java
 * These names are used to construct the path to the cgroup control dir
 */

static const char *cgroup_names[] = { NULL, "bg_non_interactive", "fg_boost" };
#define POLICY_DEBUG 0

using namespace android;

@@ -194,28 +189,6 @@ jint android_os_Process_getGidForName(JNIEnv* env, jobject clazz, jstring name)
    return -1;
}

static int add_pid_to_cgroup(int pid, int grp)
{
    int fd;
    char path[255];
    char text[64];

    sprintf(path, "/dev/cpuctl/%s/tasks",
           (cgroup_names[grp] ? cgroup_names[grp] : ""));

    if ((fd = open(path, O_WRONLY)) < 0)
        return -1;

    sprintf(text, "%d", pid);
    if (write(fd, text, strlen(text)) < 0) {
        close(fd);
        return -1;
    }

    close(fd);
    return 0;
}

void android_os_Process_setThreadGroup(JNIEnv* env, jobject clazz, int pid, jint grp)
{
    if (grp > ANDROID_TGROUP_MAX || grp < 0) { 
@@ -223,9 +196,8 @@ void android_os_Process_setThreadGroup(JNIEnv* env, jobject clazz, int pid, jint
        return;
    }

    if (add_pid_to_cgroup(pid, grp)) {
        // If the thread exited on us, don't generate an exception
        if (errno != ESRCH && errno != ENOENT)
    if (set_sched_policy(pid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
                                      SP_BACKGROUND : SP_FOREGROUND)) {
        signalExceptionForGroupError(env, clazz, errno);
    }
}
@@ -242,6 +214,26 @@ void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jin
        return;
    }

#if POLICY_DEBUG
    char cmdline[32];
    int fd;

    strcpy(cmdline, "unknown");

    sprintf(proc_path, "/proc/%d/cmdline", pid);
    fd = open(proc_path, O_RDONLY);
    if (fd >= 0) {
        int rc = read(fd, cmdline, sizeof(cmdline)-1);
        cmdline[rc] = 0;
        close(fd);
    }

    if (grp == ANDROID_TGROUP_BG_NONINTERACT) {
        LOGD("setProcessGroup: vvv pid %d (%s)", pid, cmdline);
    } else {
        LOGD("setProcessGroup: ^^^ pid %d (%s)", pid, cmdline);
    }
#endif
    sprintf(proc_path, "/proc/%d/task", pid);
    if (!(d = opendir(proc_path))) {
        // If the process exited on us, don't generate an exception
@@ -271,13 +263,10 @@ void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jin
            continue;
        }
     
        if (add_pid_to_cgroup(t_pid, grp)) {
            // If the thread exited on us, ignore it and keep going
            if (errno != ESRCH && errno != ENOENT) {
        if (set_sched_policy(t_pid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
                                            SP_BACKGROUND : SP_FOREGROUND)) {
            signalExceptionForGroupError(env, clazz, errno);
                closedir(d);
                return;
            }
            break;
        }
    }
    closedir(d);
@@ -286,10 +275,17 @@ void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jin
void android_os_Process_setThreadPriority(JNIEnv* env, jobject clazz,
                                              jint pid, jint pri)
{
    int rc = 0;

    if (pri >= ANDROID_PRIORITY_BACKGROUND) {
        add_pid_to_cgroup(pid, ANDROID_TGROUP_BG_NONINTERACT);
        rc = set_sched_policy(pid, SP_BACKGROUND);
    } else if (getpriority(PRIO_PROCESS, pid) >= ANDROID_PRIORITY_BACKGROUND) {
        add_pid_to_cgroup(pid, ANDROID_TGROUP_DEFAULT);
        rc = set_sched_policy(pid, SP_FOREGROUND);
    }

    if (rc) {
        signalExceptionForGroupError(env, clazz, errno);
        return;
    }

    if (setpriority(PRIO_PROCESS, pid, pri) < 0) {
+16 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

#include <utils/Binder.h>
#include <utils/BpBinder.h>
#include <cutils/sched_policy.h>
#include <utils/Debug.h>
#include <utils/Log.h>
#include <utils/TextOutput.h>
@@ -426,6 +427,21 @@ void IPCThreadState::joinThreadPool(bool isMain)
            result = executeCommand(cmd);
        }
        
        // After executing the command, ensure that the thread is returned to the
        // default cgroup and priority before rejoining the pool.  This is a failsafe
        // in case the command implementation failed to properly restore the thread's
        // scheduling parameters upon completion.
        int my_id;
#ifdef HAVE_GETTID
        my_id = gettid();
#else
        my_id = getpid();
#endif
        if (!set_sched_policy(my_id, SP_FOREGROUND)) {
            // success; reset the priority as well
            setpriority(PRIO_PROCESS, my_id, ANDROID_PRIORITY_NORMAL);
        }

        // Let this thread exit the thread pool if it is no longer
        // needed and it is not the main process thread.
        if(result == TIMED_OUT && !isMain) {