Loading core/jni/android_util_Process.cpp +38 −42 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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); } } Loading @@ -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 Loading Loading @@ -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); Loading @@ -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) { Loading libs/utils/IPCThreadState.cpp +16 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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) { Loading Loading
core/jni/android_util_Process.cpp +38 −42 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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); } } Loading @@ -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 Loading Loading @@ -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); Loading @@ -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) { Loading
libs/utils/IPCThreadState.cpp +16 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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) { Loading