summaryrefslogtreecommitdiffstats
path: root/core/jni/android_util_Process.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/jni/android_util_Process.cpp')
-rw-r--r--core/jni/android_util_Process.cpp81
1 files changed, 56 insertions, 25 deletions
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index d760feb..aee0ed7 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -50,8 +50,6 @@ 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
@@ -198,50 +196,82 @@ jint android_os_Process_getGidForName(JNIEnv* env, jobject clazz, jstring name)
static int add_pid_to_cgroup(int pid, int grp)
{
- FILE *fp;
+ int fd;
char path[255];
- int rc;
+ char text[64];
- sprintf(path, "/dev/cpuctl/%s/tasks", (cgroup_names[grp] ? cgroup_names[grp] : ""));
+ 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;
+ if ((fd = open(path, O_WRONLY)) < 0)
+ return -1;
+
+ sprintf(text, "%d", pid);
+ if (write(fd, text, strlen(text)) < 0) {
+ close(fd);
+ return -1;
}
- rc = fprintf(fp, "%d", pid);
- fclose(fp);
+ close(fd);
+ return 0;
+}
- 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
+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;
}
- return (rc < 0) ? errno : 0;
+ 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);
+ }
}
-void android_os_Process_setThreadGroup(JNIEnv* env, jobject clazz, int pid, jint grp)
+void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jint grp)
{
+ DIR *d;
+ FILE *fp;
+ char proc_path[255];
+ struct dirent *de;
+
if (grp > ANDROID_TGROUP_MAX || grp < 0) {
signalExceptionForGroupError(env, clazz, EINVAL);
return;
}
- if (add_pid_to_cgroup(pid, grp))
- signalExceptionForGroupError(env, clazz, errno);
+ sprintf(proc_path, "/proc/%d/task", pid);
+ if (!(d = opendir(proc_path))) {
+ // If the process exited on us, don't generate an exception
+ if (errno != ENOENT)
+ signalExceptionForGroupError(env, clazz, errno);
+ return;
+ }
+
+ while ((de = readdir(d))) {
+ if (de->d_name[0] == '.')
+ continue;
+
+ if (add_pid_to_cgroup(atoi(de->d_name), grp)) {
+ // If the thread exited on us, ignore it and keep going
+ if (errno != ESRCH && errno != ENOENT) {
+ signalExceptionForGroupError(env, clazz, errno);
+ closedir(d);
+ return;
+ }
+ }
+ }
+ closedir(d);
}
void android_os_Process_setThreadPriority(JNIEnv* env, jobject clazz,
jint pid, jint pri)
{
- if (pri == ANDROID_PRIORITY_BACKGROUND) {
+ if (pri >= ANDROID_PRIORITY_BACKGROUND) {
add_pid_to_cgroup(pid, ANDROID_TGROUP_BG_NONINTERACT);
- } else if (getpriority(PRIO_PROCESS, pid) == ANDROID_PRIORITY_BACKGROUND) {
+ } else if (getpriority(PRIO_PROCESS, pid) >= ANDROID_PRIORITY_BACKGROUND) {
add_pid_to_cgroup(pid, ANDROID_TGROUP_DEFAULT);
}
@@ -466,7 +496,7 @@ void android_os_Process_readProcLines(JNIEnv* env, jobject clazz, jstring fileSt
const String8& field = fields[i];
if (strncmp(p, field.string(), field.length()) == 0) {
p += field.length();
- while (*p == ' ') p++;
+ while (*p == ' ' || *p == '\t') p++;
char* num = p;
while (*p >= '0' && *p <= '9') p++;
skipToEol = *p != '\n';
@@ -820,6 +850,7 @@ static const JNINativeMethod methods[] = {
{"setThreadPriority", "(I)V", (void*)android_os_Process_setCallingThreadPriority},
{"getThreadPriority", "(I)I", (void*)android_os_Process_getThreadPriority},
{"setThreadGroup", "(II)V", (void*)android_os_Process_setThreadGroup},
+ {"setProcessGroup", "(II)V", (void*)android_os_Process_setProcessGroup},
{"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},