diff options
author | San Mehat <san@google.com> | 2009-04-21 14:06:36 -0700 |
---|---|---|
committer | San Mehat <san@google.com> | 2009-04-27 09:17:06 -0700 |
commit | e9d376b801b7890b1ef5006ed55de4208e64bb63 (patch) | |
tree | 9c4840944aeaccfe4c9eaf6a72a164af38f17ed1 /core/jni | |
parent | 03a54faa454381e8d67fe11b1be2b2d54f3894c6 (diff) | |
download | frameworks_base-e9d376b801b7890b1ef5006ed55de4208e64bb63.zip frameworks_base-e9d376b801b7890b1ef5006ed55de4208e64bb63.tar.gz frameworks_base-e9d376b801b7890b1ef5006ed55de4208e64bb63.tar.bz2 |
Add support for changing a threads scheduler group. Three groups are available (default, background non interactive, foreground boost). Setting a thread priority to PRIORITY_BACKGROUND will transparently change groups to background
Signed-off-by: San Mehat <san@google.com>
Diffstat (limited to 'core/jni')
-rw-r--r-- | core/jni/android_util_Process.cpp | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp index bd56605..d760feb 100644 --- a/core/jni/android_util_Process.cpp +++ b/core/jni/android_util_Process.cpp @@ -50,6 +50,16 @@ pid_t gettid() { return syscall(__NR_gettid);} #undef __KERNEL__ #endif +#define ENABLE_CGROUP_ERR_LOGGING 0 + +/* + * 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" }; + using namespace android; static void signalExceptionForPriorityError(JNIEnv* env, jobject obj, int err) @@ -73,6 +83,28 @@ static void signalExceptionForPriorityError(JNIEnv* env, jobject obj, int err) } } +static void signalExceptionForGroupError(JNIEnv* env, jobject obj, int err) +{ + switch (err) { + case EINVAL: + jniThrowException(env, "java/lang/IllegalArgumentException", NULL); + break; + case ESRCH: + jniThrowException(env, "java/lang/IllegalArgumentException", "Given thread does not exist"); + break; + case EPERM: + jniThrowException(env, "java/lang/SecurityException", "No permission to modify given thread"); + break; + case EACCES: + jniThrowException(env, "java/lang/SecurityException", "No permission to set to given group"); + break; + default: + jniThrowException(env, "java/lang/RuntimeException", "Unknown error"); + break; + } +} + + static void fakeProcessEntry(void* arg) { String8* cls = (String8*)arg; @@ -164,9 +196,55 @@ jint android_os_Process_getGidForName(JNIEnv* env, jobject clazz, jstring name) return -1; } +static int add_pid_to_cgroup(int pid, int grp) +{ + FILE *fp; + char path[255]; + int rc; + + sprintf(path, "/dev/cpuctl/%s/tasks", (cgroup_names[grp] ? cgroup_names[grp] : "")); + + if (!(fp = fopen(path, "w"))) { +#if ENABLE_CGROUP_ERR_LOGGING + LOGW("Unable to open %s (%s)\n", path, strerror(errno)); +#endif + return -errno; + } + + rc = fprintf(fp, "%d", pid); + fclose(fp); + + if (rc < 0) { +#if ENABLE_CGROUP_ERR_LOGGING + LOGW("Unable to move pid %d to cgroup %s (%s)\n", pid, + (cgroup_names[grp] ? cgroup_names[grp] : "<default>"), + strerror(errno)); +#endif + } + + return (rc < 0) ? errno : 0; +} + +void android_os_Process_setThreadGroup(JNIEnv* env, jobject clazz, int pid, jint grp) +{ + if (grp > ANDROID_TGROUP_MAX || grp < 0) { + signalExceptionForGroupError(env, clazz, EINVAL); + return; + } + + if (add_pid_to_cgroup(pid, grp)) + signalExceptionForGroupError(env, clazz, errno); +} + void android_os_Process_setThreadPriority(JNIEnv* env, jobject clazz, jint pid, jint pri) { + if (pri == ANDROID_PRIORITY_BACKGROUND) { + add_pid_to_cgroup(pid, ANDROID_TGROUP_BG_NONINTERACT); + } else if (getpriority(PRIO_PROCESS, pid) == ANDROID_PRIORITY_BACKGROUND) { + add_pid_to_cgroup(pid, ANDROID_TGROUP_DEFAULT); + } + if (setpriority(PRIO_PROCESS, pid, pri) < 0) { signalExceptionForPriorityError(env, clazz, errno); } @@ -741,6 +819,7 @@ static const JNINativeMethod methods[] = { {"setThreadPriority", "(II)V", (void*)android_os_Process_setThreadPriority}, {"setThreadPriority", "(I)V", (void*)android_os_Process_setCallingThreadPriority}, {"getThreadPriority", "(I)I", (void*)android_os_Process_getThreadPriority}, + {"setThreadGroup", "(II)V", (void*)android_os_Process_setThreadGroup}, {"setOomAdj", "(II)Z", (void*)android_os_Process_setOomAdj}, {"setArgV0", "(Ljava/lang/String;)V", (void*)android_os_Process_setArgV0}, {"setUid", "(I)I", (void*)android_os_Process_setUid}, |