1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #define LOG_TAG "ActivityManagerService" 18 //#define LOG_NDEBUG 0 19 20 #include <android_runtime/AndroidRuntime.h> 21 #include <jni.h> 22 23 #include <ScopedLocalRef.h> 24 #include <ScopedPrimitiveArray.h> 25 26 #include <cutils/log.h> 27 #include <utils/misc.h> 28 #include <utils/Log.h> 29 30 #include <stdio.h> 31 #include <errno.h> 32 #include <fcntl.h> 33 #include <semaphore.h> 34 #include <stddef.h> 35 #include <string.h> 36 #include <sys/stat.h> 37 #include <sys/types.h> 38 #include <unistd.h> 39 40 namespace android 41 { 42 43 // migrate from foreground to foreground_boost migrateToBoost(JNIEnv * env,jobject _this)44 static jint migrateToBoost(JNIEnv *env, jobject _this) 45 { 46 #ifdef USE_SCHED_BOOST 47 // File descriptors open to /dev/cpuset/../tasks, setup by initialize, or -1 on error 48 FILE* fg_cpuset_file = NULL; 49 int boost_cpuset_fd = 0; 50 if (!access("/dev/cpuset/tasks", F_OK)) { 51 fg_cpuset_file = fopen("/dev/cpuset/foreground/tasks", "r+"); 52 if (ferror(fg_cpuset_file)) { 53 return 0; 54 } 55 boost_cpuset_fd = open("/dev/cpuset/foreground/boost/tasks", O_WRONLY); 56 if (boost_cpuset_fd < 0) { 57 fclose(fg_cpuset_file); 58 return 0; 59 } 60 61 } 62 if (!fg_cpuset_file || !boost_cpuset_fd) { 63 fclose(fg_cpuset_file); 64 close(boost_cpuset_fd); 65 return 0; 66 } 67 char buf[17]; 68 while (fgets(buf, 16, fg_cpuset_file)) { 69 int i = 0; 70 for (; i < 16; i++) { 71 if (buf[i] == '\n') { 72 buf[i] = 0; 73 break; 74 } 75 } 76 if (write(boost_cpuset_fd, buf, i) < 0) { 77 // ignore error 78 } 79 if (feof(fg_cpuset_file)) 80 break; 81 } 82 fclose(fg_cpuset_file); 83 close(boost_cpuset_fd); 84 #endif 85 return 0; 86 } 87 88 // migrate from foreground_boost to foreground migrateFromBoost(JNIEnv * env,jobject _this)89 static jint migrateFromBoost(JNIEnv *env, jobject _this) 90 { 91 #ifdef USE_SCHED_BOOST 92 // File descriptors open to /dev/cpuset/../tasks, setup by initialize, or -1 on error 93 int fg_cpuset_fd = 0; 94 FILE* boost_cpuset_file = NULL; 95 if (!access("/dev/cpuset/tasks", F_OK)) { 96 boost_cpuset_file = fopen("/dev/cpuset/foreground/boost/tasks", "r+"); 97 if (ferror(boost_cpuset_file)) { 98 return 0; 99 } 100 fg_cpuset_fd = open("/dev/cpuset/foreground/tasks", O_WRONLY); 101 if (fg_cpuset_fd < 0) { 102 fclose(boost_cpuset_file); 103 return 0; 104 } 105 106 } 107 if (!boost_cpuset_file || !fg_cpuset_fd) { 108 fclose(boost_cpuset_file); 109 close(fg_cpuset_fd); 110 return 0; 111 } 112 char buf[17]; 113 while (fgets(buf, 16, boost_cpuset_file)) { 114 //ALOGE("Appending FD %s to fg", buf); 115 int i = 0; 116 for (; i < 16; i++) { 117 if (buf[i] == '\n') { 118 buf[i] = 0; 119 break; 120 } 121 } 122 if (write(fg_cpuset_fd, buf, i) < 0) { 123 //ALOGE("Appending FD %s to fg ERROR", buf); 124 // handle error? 125 } 126 if (feof(boost_cpuset_file)) 127 break; 128 } 129 130 close(fg_cpuset_fd); 131 fclose(boost_cpuset_file); 132 133 #endif 134 return 0; 135 136 } 137 138 139 static JNINativeMethod method_table[] = { 140 { "nativeMigrateToBoost", "()I", (void*)migrateToBoost }, 141 { "nativeMigrateFromBoost", "()I", (void*)migrateFromBoost }, 142 }; 143 register_android_server_ActivityManagerService(JNIEnv * env)144 int register_android_server_ActivityManagerService(JNIEnv *env) 145 { 146 return jniRegisterNativeMethods(env, "com/android/server/am/ActivityManagerService", 147 method_table, NELEM(method_table)); 148 } 149 150 } 151