summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Tate <ctate@google.com>2009-12-03 15:23:40 -0800
committerandroid-build SharedAccount <android-build@sekiwake.mtv.corp.google.com>2009-12-03 17:45:47 -0800
commita16a12a27d1f25c3f3aa5f9a10fd202df785a82d (patch)
tree8ce39253bf58c3cb1246cf3cecf0d699e525af33
parent72227984b0000fc32aa31614a8cdd662266385f6 (diff)
downloadbase-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.cpp80
-rw-r--r--libs/utils/IPCThreadState.cpp16
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) {