diff options
author | Christopher Tate <ctate@google.com> | 2009-12-03 15:23:40 -0800 |
---|---|---|
committer | android-build SharedAccount <android-build@sekiwake.mtv.corp.google.com> | 2009-12-03 17:45:47 -0800 |
commit | a16a12a27d1f25c3f3aa5f9a10fd202df785a82d (patch) | |
tree | 8ce39253bf58c3cb1246cf3cecf0d699e525af33 | |
parent | 72227984b0000fc32aa31614a8cdd662266385f6 (diff) | |
download | base-donut-release2.tar.gz |
DO NOT MERGE - backport Eclair binder thread pool scheduling policyandroid-1.6_r1.5donut-release2
-rw-r--r-- | core/jni/android_util_Process.cpp | 80 | ||||
-rw-r--r-- | libs/utils/IPCThreadState.cpp | 16 |
2 files changed, 54 insertions, 42 deletions
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp index 98fe0e654e14..cb77cc15a45c 100644 --- a/core/jni/android_util_Process.cpp +++ b/core/jni/android_util_Process.cpp @@ -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,10 +196,9 @@ 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) - signalExceptionForGroupError(env, clazz, errno); + 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) { - signalExceptionForGroupError(env, clazz, errno); - closedir(d); - return; - } + if (set_sched_policy(t_pid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ? + SP_BACKGROUND : SP_FOREGROUND)) { + signalExceptionForGroupError(env, clazz, errno); + 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) { diff --git a/libs/utils/IPCThreadState.cpp b/libs/utils/IPCThreadState.cpp index 04ae1424e42e..47160e1dbe07 100644 --- a/libs/utils/IPCThreadState.cpp +++ b/libs/utils/IPCThreadState.cpp @@ -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) { |