2 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <sys/types.h>
23 #include <device-node.h>
26 #include "include/ss_data.h"
30 #define LIMITED_BACKGRD_NUM 15
31 #define MAX_BACKGRD_OOMADJ (OOMADJ_BACKGRD_UNLOCKED + LIMITED_BACKGRD_NUM)
32 #define PROCESS_VIP "process_vip"
33 #define PROCESS_PERMANENT "process_permanent"
35 int get_app_oomadj(int pid, int *oomadj)
43 snprintf(buf, sizeof(buf), "/proc/%d/oom_adj", pid);
47 if (fgets(buf, PATH_MAX, fp) == NULL) {
51 (*oomadj) = atoi(buf);
56 int set_app_oomadj(pid_t pid, int new_oomadj)
61 char exe_name[PATH_MAX];
63 if (sysman_get_cmdline_name(pid, exe_name, PATH_MAX) < 0)
64 snprintf(exe_name, sizeof(exe_name), "Unknown (maybe dead)");
66 snprintf(buf, sizeof(buf), "/proc/%d/oom_adj", pid);
70 if (fgets(buf, PATH_MAX, fp) == NULL) {
74 old_oomadj = atoi(buf);
76 PRT_TRACE_EM("Process %s, pid %d, old_oomadj %d", exe_name, pid,
79 if (old_oomadj < OOMADJ_APP_LIMIT)
82 PRT_TRACE_EM("Process %s, pid %d, new_oomadj %d", exe_name, pid,
84 snprintf(buf, sizeof(buf), "/proc/%d/oom_adj", pid);
89 fprintf(fp, "%d", new_oomadj);
95 int set_oomadj_action(int argc, char **argv)
102 if ((pid = atoi(argv[0])) < 0 || (new_oomadj = atoi(argv[1])) <= -20)
108 PRT_TRACE_EM("OOMADJ_SET : pid %d, new_oomadj %d", pid, new_oomadj);
109 snprintf(buf, sizeof(buf), "/proc/%d/oom_adj", pid);
110 fp = fopen(buf, "w");
113 fprintf(fp, "%d", new_oomadj);
119 static int update_backgrd_app_oomadj(pid_t pid, int new_oomadj)
124 snprintf(buf, sizeof(buf), "/proc/%d/oom_adj", pid);
125 fp = fopen(buf, "w");
129 fprintf(fp, "%d", new_oomadj);
135 int check_and_set_old_backgrd()
139 struct dirent *dentry;
143 int oom_adj, new_oomadj, i;
144 pid_t buckets[MAX_BACKGRD_OOMADJ][LIMITED_BACKGRD_NUM];
146 dp = opendir("/proc");
148 PRT_TRACE_EM("BACKGRD MANAGE : fail to open /proc : %s", strerror(errno));
152 memset(buckets, 0, sizeof(buckets));
153 while ((dentry = readdir(dp)) != NULL) {
154 if (!isdigit(dentry->d_name[0]))
157 pid = atoi(dentry->d_name);
159 snprintf(buf, sizeof(buf), "/proc/%d/oom_adj", pid);
160 fp = fopen(buf, "r");
163 if (fgets(buf, sizeof(buf), fp) == NULL) {
168 if (oom_adj < MAX_BACKGRD_OOMADJ && oom_adj >= OOMADJ_BACKGRD_UNLOCKED) {
169 pid_t *bucket = buckets[oom_adj];
170 for (i = 0; i < LIMITED_BACKGRD_NUM; i++) {
174 if (i >= LIMITED_BACKGRD_NUM)
175 PRT_TRACE_EM("BACKGRB MANAGE : background applications(oom_adj %d) exceeds limitation", i);
183 new_oomadj = OOMADJ_BACKGRD_UNLOCKED + 1;
184 for (oom_adj = OOMADJ_BACKGRD_UNLOCKED; oom_adj < MAX_BACKGRD_OOMADJ; oom_adj++) {
185 for (i = 0; i < LIMITED_BACKGRD_NUM; i++) {
186 pid = buckets[oom_adj][i];
189 if (new_oomadj >= MAX_BACKGRD_OOMADJ) {
190 PRT_TRACE("BACKGRD MANAGE : kill the process %d (oom_adj %d)", pid, MAX_BACKGRD_OOMADJ);
194 if (new_oomadj != oom_adj)
195 update_backgrd_app_oomadj(pid, new_oomadj);
204 int set_active_action(int argc, char **argv)
212 if ((pid = atoi(argv[0])) < 0)
215 if (get_app_oomadj(pid, &oomadj) < 0)
219 case OOMADJ_FOREGRD_LOCKED:
220 case OOMADJ_BACKGRD_LOCKED:
224 case OOMADJ_FOREGRD_UNLOCKED:
225 ret = set_app_oomadj((pid_t) pid, OOMADJ_FOREGRD_LOCKED);
227 case OOMADJ_BACKGRD_UNLOCKED:
228 ret = set_app_oomadj((pid_t) pid, OOMADJ_BACKGRD_LOCKED);
231 ret = set_app_oomadj((pid_t) pid, OOMADJ_BACKGRD_LOCKED);
234 if(oomadj > OOMADJ_BACKGRD_UNLOCKED) {
235 ret = set_app_oomadj((pid_t) pid, OOMADJ_BACKGRD_LOCKED);
237 PRT_TRACE_EM("Unknown oomadj value (%d) !", oomadj);
245 int set_inactive_action(int argc, char **argv)
253 if ((pid = atoi(argv[0])) < 0)
256 if (get_app_oomadj(pid, &oomadj) < 0)
260 case OOMADJ_FOREGRD_UNLOCKED:
261 case OOMADJ_BACKGRD_UNLOCKED:
265 case OOMADJ_FOREGRD_LOCKED:
266 ret = set_app_oomadj((pid_t) pid, OOMADJ_FOREGRD_UNLOCKED);
268 case OOMADJ_BACKGRD_LOCKED:
269 check_and_set_old_backgrd();
270 ret = set_app_oomadj((pid_t) pid, OOMADJ_BACKGRD_UNLOCKED);
273 check_and_set_old_backgrd();
274 ret = set_app_oomadj((pid_t) pid, OOMADJ_BACKGRD_UNLOCKED);
277 if(oomadj > OOMADJ_BACKGRD_UNLOCKED) {
280 PRT_TRACE_EM("Unknown oomadj value (%d) !", oomadj);
289 int set_foregrd_action(int argc, char **argv)
297 if ((pid = atoi(argv[0])) < 0)
300 if (get_app_oomadj(pid, &oomadj) < 0)
304 case OOMADJ_FOREGRD_LOCKED:
305 case OOMADJ_FOREGRD_UNLOCKED:
309 case OOMADJ_BACKGRD_LOCKED:
310 ret = set_app_oomadj((pid_t) pid, OOMADJ_FOREGRD_LOCKED);
312 case OOMADJ_BACKGRD_UNLOCKED:
313 ret = set_app_oomadj((pid_t) pid, OOMADJ_FOREGRD_UNLOCKED);
316 ret = set_app_oomadj((pid_t) pid, OOMADJ_FOREGRD_UNLOCKED);
319 if(oomadj > OOMADJ_BACKGRD_UNLOCKED) {
320 ret = set_app_oomadj((pid_t) pid, OOMADJ_FOREGRD_UNLOCKED);
322 PRT_TRACE_EM("Unknown oomadj value (%d) !", oomadj);
331 int set_backgrd_action(int argc, char **argv)
339 if ((pid = atoi(argv[0])) < 0)
342 if (get_app_oomadj(pid, &oomadj) < 0)
346 case OOMADJ_BACKGRD_LOCKED:
347 case OOMADJ_BACKGRD_UNLOCKED:
351 case OOMADJ_FOREGRD_LOCKED:
352 ret = set_app_oomadj((pid_t) pid, OOMADJ_BACKGRD_LOCKED);
354 case OOMADJ_FOREGRD_UNLOCKED:
355 check_and_set_old_backgrd();
356 ret = set_app_oomadj((pid_t) pid, OOMADJ_BACKGRD_UNLOCKED);
359 check_and_set_old_backgrd();
360 ret = set_app_oomadj((pid_t) pid, OOMADJ_BACKGRD_UNLOCKED);
363 if(oomadj > OOMADJ_BACKGRD_UNLOCKED) {
366 PRT_TRACE_EM("Unknown oomadj value (%d) !", oomadj);
374 int set_process_group_action(int argc, char **argv)
381 if ((pid = atoi(argv[0])) < 0)
384 if (strncmp(argv[1], PROCESS_VIP, strlen(PROCESS_VIP)) == 0)
385 ret = device_set_property(DEVICE_TYPE_PROCESS, PROP_PROCESS_MP_VIP, pid);
386 else if (strncmp(argv[1], PROCESS_PERMANENT, strlen(PROCESS_PERMANENT)) == 0)
387 ret = device_set_property(DEVICE_TYPE_PROCESS, PROP_PROCESS_MP_PNP, pid);
390 PRT_TRACE_ERR("%s : pid %d", argv[1], pid);
392 PRT_TRACE_ERR("fail to set %s : pid %d",argv[1], pid);
396 int ss_process_manager_init(void)
398 ss_action_entry_add_internal(PREDEF_FOREGRD, set_foregrd_action, NULL,
400 ss_action_entry_add_internal(PREDEF_BACKGRD, set_backgrd_action, NULL,
402 ss_action_entry_add_internal(PREDEF_ACTIVE, set_active_action, NULL,
404 ss_action_entry_add_internal(PREDEF_INACTIVE, set_inactive_action, NULL,
406 ss_action_entry_add_internal(OOMADJ_SET, set_oomadj_action, NULL, NULL);
407 ss_action_entry_add_internal(PROCESS_GROUP_SET, set_process_group_action, NULL, NULL);