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>
25 #include "include/ss_data.h"
29 #define LIMITED_BACKGRD_NUM 15
30 #define MAX_BACKGRD_OOMADJ (OOMADJ_BACKGRD_UNLOCKED + LIMITED_BACKGRD_NUM)
32 int get_app_oomadj(int pid, int *oomadj)
40 snprintf(buf, sizeof(buf), "/proc/%d/oom_adj", pid);
44 if (fgets(buf, PATH_MAX, fp) == NULL) {
48 (*oomadj) = atoi(buf);
53 int set_app_oomadj(pid_t pid, int new_oomadj)
58 char exe_name[PATH_MAX];
60 if (sysman_get_cmdline_name(pid, exe_name, PATH_MAX) < 0)
61 snprintf(exe_name, sizeof(exe_name), "Unknown (maybe dead)");
63 snprintf(buf, sizeof(buf), "/proc/%d/oom_adj", pid);
67 if (fgets(buf, PATH_MAX, fp) == NULL) {
71 old_oomadj = atoi(buf);
73 PRT_TRACE_EM("Process %s, pid %d, old_oomadj %d", exe_name, pid,
76 if (old_oomadj < OOMADJ_APP_LIMIT)
79 PRT_TRACE_EM("Process %s, pid %d, new_oomadj %d", exe_name, pid,
81 snprintf(buf, sizeof(buf), "/proc/%d/oom_adj", pid);
86 fprintf(fp, "%d", new_oomadj);
92 int set_oomadj_action(int argc, char **argv)
99 if ((pid = atoi(argv[0])) < 0 || (new_oomadj = atoi(argv[1])) <= -20)
105 PRT_TRACE_EM("OOMADJ_SET : pid %d, new_oomadj %d", pid, new_oomadj);
106 snprintf(buf, sizeof(buf), "/proc/%d/oom_adj", pid);
107 fp = fopen(buf, "w");
110 fprintf(fp, "%d", new_oomadj);
116 static int update_backgrd_app_oomadj(pid_t pid, int new_oomadj)
121 snprintf(buf, sizeof(buf), "/proc/%d/oom_adj", pid);
122 fp = fopen(buf, "w");
126 fprintf(fp, "%d", new_oomadj);
132 int check_and_set_old_backgrd()
136 struct dirent *dentry;
140 int oom_adj, new_oomadj, i;
141 pid_t buckets[MAX_BACKGRD_OOMADJ][LIMITED_BACKGRD_NUM];
143 dp = opendir("/proc");
145 PRT_TRACE_EM("BACKGRD MANAGE : fail to open /proc : %s", strerror(errno));
149 memset(buckets, 0, sizeof(buckets));
150 while ((dentry = readdir(dp)) != NULL) {
151 if (!isdigit(dentry->d_name[0]))
154 pid = atoi(dentry->d_name);
156 snprintf(buf, sizeof(buf), "/proc/%d/oom_adj", pid);
157 fp = fopen(buf, "r");
160 if (fgets(buf, sizeof(buf), fp) == NULL) {
165 if (oom_adj < MAX_BACKGRD_OOMADJ && oom_adj >= OOMADJ_BACKGRD_UNLOCKED) {
166 pid_t *bucket = buckets[oom_adj];
167 for (i = 0; i < LIMITED_BACKGRD_NUM; i++) {
171 if (i >= LIMITED_BACKGRD_NUM)
172 PRT_TRACE_EM("BACKGRB MANAGE : background applications(oom_adj %d) exceeds limitation", i);
180 new_oomadj = OOMADJ_BACKGRD_UNLOCKED + 1;
181 for (oom_adj = OOMADJ_BACKGRD_UNLOCKED; oom_adj < MAX_BACKGRD_OOMADJ; oom_adj++) {
182 for (i = 0; i < LIMITED_BACKGRD_NUM; i++) {
183 pid = buckets[oom_adj][i];
186 if (new_oomadj >= MAX_BACKGRD_OOMADJ) {
187 PRT_TRACE("BACKGRD MANAGE : kill the process %d (oom_adj %d)", pid, MAX_BACKGRD_OOMADJ);
191 if (new_oomadj != oom_adj)
192 update_backgrd_app_oomadj(pid, new_oomadj);
201 int set_active_action(int argc, char **argv)
209 if ((pid = atoi(argv[0])) < 0)
212 if (get_app_oomadj(pid, &oomadj) < 0)
216 case OOMADJ_FOREGRD_LOCKED:
217 case OOMADJ_BACKGRD_LOCKED:
221 case OOMADJ_FOREGRD_UNLOCKED:
222 ret = set_app_oomadj((pid_t) pid, OOMADJ_FOREGRD_LOCKED);
224 case OOMADJ_BACKGRD_UNLOCKED:
225 ret = set_app_oomadj((pid_t) pid, OOMADJ_BACKGRD_LOCKED);
228 ret = set_app_oomadj((pid_t) pid, OOMADJ_BACKGRD_LOCKED);
231 if(oomadj > OOMADJ_BACKGRD_UNLOCKED) {
232 ret = set_app_oomadj((pid_t) pid, OOMADJ_BACKGRD_LOCKED);
234 PRT_TRACE_EM("Unknown oomadj value (%d) !", oomadj);
242 int set_inactive_action(int argc, char **argv)
250 if ((pid = atoi(argv[0])) < 0)
253 if (get_app_oomadj(pid, &oomadj) < 0)
257 case OOMADJ_FOREGRD_UNLOCKED:
258 case OOMADJ_BACKGRD_UNLOCKED:
262 case OOMADJ_FOREGRD_LOCKED:
263 ret = set_app_oomadj((pid_t) pid, OOMADJ_FOREGRD_UNLOCKED);
265 case OOMADJ_BACKGRD_LOCKED:
266 check_and_set_old_backgrd();
267 ret = set_app_oomadj((pid_t) pid, OOMADJ_BACKGRD_UNLOCKED);
270 check_and_set_old_backgrd();
271 ret = set_app_oomadj((pid_t) pid, OOMADJ_BACKGRD_UNLOCKED);
274 if(oomadj > OOMADJ_BACKGRD_UNLOCKED) {
277 PRT_TRACE_EM("Unknown oomadj value (%d) !", oomadj);
286 int set_foregrd_action(int argc, char **argv)
294 if ((pid = atoi(argv[0])) < 0)
297 if (get_app_oomadj(pid, &oomadj) < 0)
301 case OOMADJ_FOREGRD_LOCKED:
302 case OOMADJ_FOREGRD_UNLOCKED:
306 case OOMADJ_BACKGRD_LOCKED:
307 ret = set_app_oomadj((pid_t) pid, OOMADJ_FOREGRD_LOCKED);
309 case OOMADJ_BACKGRD_UNLOCKED:
310 ret = set_app_oomadj((pid_t) pid, OOMADJ_FOREGRD_UNLOCKED);
313 ret = set_app_oomadj((pid_t) pid, OOMADJ_FOREGRD_UNLOCKED);
316 if(oomadj > OOMADJ_BACKGRD_UNLOCKED) {
317 ret = set_app_oomadj((pid_t) pid, OOMADJ_FOREGRD_UNLOCKED);
319 PRT_TRACE_EM("Unknown oomadj value (%d) !", oomadj);
328 int set_backgrd_action(int argc, char **argv)
336 if ((pid = atoi(argv[0])) < 0)
339 if (get_app_oomadj(pid, &oomadj) < 0)
343 case OOMADJ_BACKGRD_LOCKED:
344 case OOMADJ_BACKGRD_UNLOCKED:
348 case OOMADJ_FOREGRD_LOCKED:
349 ret = set_app_oomadj((pid_t) pid, OOMADJ_BACKGRD_LOCKED);
351 case OOMADJ_FOREGRD_UNLOCKED:
352 check_and_set_old_backgrd();
353 ret = set_app_oomadj((pid_t) pid, OOMADJ_BACKGRD_UNLOCKED);
356 check_and_set_old_backgrd();
357 ret = set_app_oomadj((pid_t) pid, OOMADJ_BACKGRD_UNLOCKED);
360 if(oomadj > OOMADJ_BACKGRD_UNLOCKED) {
363 PRT_TRACE_EM("Unknown oomadj value (%d) !", oomadj);
371 int ss_process_manager_init(void)
373 ss_action_entry_add_internal(PREDEF_FOREGRD, set_foregrd_action, NULL,
375 ss_action_entry_add_internal(PREDEF_BACKGRD, set_backgrd_action, NULL,
377 ss_action_entry_add_internal(PREDEF_ACTIVE, set_active_action, NULL,
379 ss_action_entry_add_internal(PREDEF_INACTIVE, set_inactive_action, NULL,
381 ss_action_entry_add_internal(OOMADJ_SET, set_oomadj_action, NULL, NULL);