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