*/
static struct memcg_info *memcg_root;
+struct proc_info {
+ pid_t pid;
+ char cmdline[PROC_NAME_MAX];
+};
+static GPtrArray *proc_apps;
+static GPtrArray *vip_apps;
+
static char *convert_memstate_to_str(int mem_state)
{
char *tmp = NULL;
static int load_vip_config(struct parse_result *result, void *user_data)
{
- pid_t pid = 0;
- if (!result)
- return -EINVAL;
+ if (!result || !vip_apps)
+ return RESOURCED_ERROR_INVALID_PARAMETER;
- if (strncmp(result->section, MEM_VIP_SECTION, strlen(MEM_VIP_SECTION)+1))
+ if (strncmp(result->section, MEM_VIP_SECTION, sizeof(MEM_VIP_SECTION)))
return RESOURCED_ERROR_NONE;
- if (!strncmp(result->name, MEM_VIP_PREDEFINE, strlen(MEM_VIP_PREDEFINE)+1)) {
- pid = find_pid_from_cmdline(result->value);
- if (pid > 0)
- proc_set_oom_score_adj(pid, OOMADJ_SERVICE_MIN);
+ if (!strcmp(result->name, MEM_VIP_PREDEFINE)) {
+ char *app_name = g_strdup(result->value);
+ g_ptr_array_add(vip_apps, (gpointer)app_name);
}
+
return RESOURCED_ERROR_NONE;
}
static int load_mem_config(struct parse_result *result, void *user_data)
{
if (!result)
- return -EINVAL;
+ return RESOURCED_ERROR_INVALID_PARAMETER;
if (strncmp(result->section, MEM_POPUP_SECTION, strlen(MEM_POPUP_SECTION)+1))
return RESOURCED_ERROR_NONE;
return RESOURCED_ERROR_NONE;
}
+static void set_vip_oom_score_adj(gpointer vip_app)
+{
+ int proc_index = 0;
+ struct proc_info *info;
+
+ for(proc_index = 0; proc_index < proc_apps->len; proc_index++) {
+ info = g_ptr_array_index(proc_apps, proc_index);
+ if(!strncmp(vip_app, info->cmdline, strlen(info->cmdline) + 1)) {
+ if (info->pid > 0) {
+ proc_set_oom_score_adj(info->pid, OOMADJ_SERVICE_MIN);
+ break;
+ }
+ }
+ }
+}
+
+static void free_app_list(void)
+{
+ if(proc_apps) {
+ g_ptr_array_foreach(proc_apps, (GFunc)g_free, NULL);
+ g_ptr_array_free(proc_apps, true);
+ proc_apps = NULL;
+ }
+
+ if(vip_apps) {
+ g_ptr_array_foreach(vip_apps, (GFunc)g_free, NULL);
+ g_ptr_array_free(vip_apps, true);
+ vip_apps = NULL;
+ }
+}
+
+static int allocate_app_list(void)
+{
+ vip_apps = g_ptr_array_new();
+ if(!vip_apps) {
+ _E("lowmem : out of memory");
+ return RESOURCED_ERROR_OUT_OF_MEMORY;
+ }
+
+ proc_apps = g_ptr_array_new();
+ if(!proc_apps) {
+ _E("lowmem : out of memory");
+ free_app_list();
+ return RESOURCED_ERROR_OUT_OF_MEMORY;
+ }
+
+ return RESOURCED_ERROR_NONE;
+}
+
+static int set_vip_list(void)
+{
+ pid_t pid = -1;
+ int ret = 0;
+ DIR *dp;
+ struct dirent dentry;
+ struct dirent *result;
+ char appname[PROC_NAME_MAX];
+ int appname_len;
+ struct proc_info *info;
+
+ if (!proc_apps)
+ return RESOURCED_ERROR_INVALID_PARAMETER;
+
+ /* load all (appname,pid) pairs in the /proc to the proc_apps*/
+ dp = opendir("/proc");
+ if (!dp) {
+ _E("fail to open /proc");
+ return RESOURCED_ERROR_FAIL;
+ }
+
+ while(!readdir_r(dp, &dentry, &result) && result != NULL) {
+ if (!isdigit(dentry.d_name[0]))
+ continue;
+
+ pid = atoi(dentry.d_name);
+ if(!pid)
+ continue;
+ ret = proc_get_cmdline(pid, appname);
+
+ if (ret == RESOURCED_ERROR_NONE) {
+ info = (struct proc_info *)malloc(sizeof(struct proc_info)); // check malloc
+ info->pid = pid;
+ appname_len = strlen(appname);
+ strncpy(info->cmdline, appname, appname_len);
+ info->cmdline[appname_len] = '\0';
+ g_ptr_array_add(proc_apps, (gpointer)info);
+ }
+ }
+ closedir(dp);
+
+ g_ptr_array_foreach(vip_apps, (GFunc)set_vip_oom_score_adj, NULL);
+
+ return RESOURCED_ERROR_NONE;
+}
+
/* To Do: should we need lowmem_fd_start, lowmem_fd_stop ?? */
int lowmem_init(void)
{
init_memcg_params();
setup_memcg_params();
- config_parse(MEM_CONF_FILE, load_vip_config, NULL);
+
+ if(allocate_app_list() != RESOURCED_ERROR_NONE)
+ _E("allocate_proc_list FAIL");
+
+ if(config_parse(MEM_CONF_FILE, load_vip_config, NULL))
+ _E("(%s) parse Fail", MEM_CONF_FILE);
+
+ if(set_vip_list() != RESOURCED_ERROR_NONE)
+ _E("set_vip_list FAIL");
+
+ /* Free the GPtrArray's as these are not required anymore. */
+ free_app_list();
+
config_parse(MEM_CONF_FILE, load_mem_config, NULL);
create_memcgs();
ret = oom_thread_create();
if (ret) {
- _E("oom thread create failed\n");
+ _E("oom thread create failed");
return ret;
}