DO NOT MERGE - backport Eclair binder thread pool scheduling policy
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 98fe0e6..cb77cc1 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 @@
 #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 @@
     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 @@
         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 @@
         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 @@
             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_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 04ae142..47160e1 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 @@
             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) {