From 35303ec4e4c76fa9a66adbf241094672e07ca11a Mon Sep 17 00:00:00 2001 From: Kichan Kwon Date: Sat, 5 Nov 2016 17:55:57 +0900 Subject: [PATCH] proc-stat : create critical section for proc_app_list - System-freezer will link proc_app_list functions to use it Change-Id: I57acaba1bee806e98e7f42bdf4529a892cdb7dae Signed-off-by: Kichan Kwon --- src/common/proc-common.h | 3 -- src/freezer/freezer.c | 5 ++- src/heart/heart-cpu.c | 3 ++ src/proc-stat/include/proc-main.h | 18 ++++++++++ src/proc-stat/proc-main.c | 69 ++++++++++++++++++++++++++++++++++++--- src/proc-stat/proc-monitor.c | 8 +++++ src/proc-stat/proc-process.c | 4 +++ src/swap/swap.c | 2 ++ 8 files changed, 104 insertions(+), 8 deletions(-) diff --git a/src/common/proc-common.h b/src/common/proc-common.h index ec749a5..f121390 100644 --- a/src/common/proc-common.h +++ b/src/common/proc-common.h @@ -143,9 +143,6 @@ enum cgroup_cmd_type { /** cgroup command type **/ PROC_CGROUP_GET_PGID_CMDLINE, }; - -extern GSList *proc_app_list; - struct proc_exclude { pid_t pid; enum proc_exclude_type type; diff --git a/src/freezer/freezer.c b/src/freezer/freezer.c index ae5b47d..a7cc79f 100644 --- a/src/freezer/freezer.c +++ b/src/freezer/freezer.c @@ -39,6 +39,7 @@ #include "config-parser.h" #include "procfs.h" #include "proc-common.h" +#include "proc-main.h" #include "freezer.h" #define FREEZER_MODULE_PATH SYSTEM_LIB_PATH"/libsystem-freezer.so.0" @@ -231,12 +232,14 @@ error: return RESOURCED_ERROR_FAIL; } +extern struct proc_app_list app_list; + static int resourced_freezer_init(void *data) { int ret_code; bool is_suspend; bool is_present; - struct freezer_init_data init_data = { .resourced_app_list = &proc_app_list }; + struct freezer_init_data init_data = { .resourced_app_list = &(app_list.list) }; is_present = freezer_is_present(); if (!is_present) { diff --git a/src/heart/heart-cpu.c b/src/heart/heart-cpu.c index e892d42..6d6d870 100644 --- a/src/heart/heart-cpu.c +++ b/src/heart/heart-cpu.c @@ -41,6 +41,7 @@ #include "module.h" #include "macro.h" #include "userinfo-list.h" +#include "proc-main.h" #define PROC_PATH "/proc/%d" #define PROC_STAT_PATH "/proc/%d/stat" @@ -280,9 +281,11 @@ static int heart_cpu_update_state(void *data) static int heart_cpu_update_app_list(void *data) { + _cleanup_app_list_close_ GSList *proc_app_list = NULL; GSList *giter = NULL; struct proc_app_info *pai = NULL; + proc_app_list = proc_app_list_open(); gslist_for_each_item(giter, proc_app_list) { struct proc_status ps; pai = (struct proc_app_info *)giter->data; diff --git a/src/proc-stat/include/proc-main.h b/src/proc-stat/include/proc-main.h index 1cb5da3..a8c0dcb 100644 --- a/src/proc-stat/include/proc-main.h +++ b/src/proc-stat/include/proc-main.h @@ -33,6 +33,14 @@ #include "resourced.h" #include "const.h" +struct proc_app_list { + GSList *list; + pthread_mutex_t lock; + pid_t tid; + uint32_t ref; +}; +extern struct proc_app_list app_list; + struct proc_module_ops { char *name; int (*init) (void *data); @@ -75,4 +83,14 @@ void proc_set_group(pid_t ownerpid, pid_t childpid, char *pkgname); int proc_get_state(int type, pid_t pid, char *buf, int len); +GSList *proc_app_list_open(void); +void proc_app_list_close(void); + +static inline void cleanup_proc_app_list_close_func(GSList **l) +{ + proc_app_list_close(); +} + +#define _cleanup_app_list_close_ __attribute__((cleanup(cleanup_proc_app_list_close_func))) + #endif /*__PROC_MAIN_H__ */ diff --git a/src/proc-stat/proc-main.c b/src/proc-stat/proc-main.c index d40af96..c7d037c 100644 --- a/src/proc-stat/proc-main.c +++ b/src/proc-stat/proc-main.c @@ -50,6 +50,16 @@ #include "file-helper.h" #include "config-parser.h" +#ifndef gettid +#include + +#ifdef SYS_gettid +#define gettid() (pid_t) syscall(SYS_gettid) +#else +#error "SYS_gettid unavailable on this system" +#endif +#endif + static GHashTable *proc_exclude_list; static Ecore_File_Monitor *exclude_list_monitor; static const unsigned int exclude_list_limit = 1024; @@ -59,9 +69,38 @@ static GSList *proc_module; /* proc sub-module list */ #define LOG_PREFIX "resourced" #define TIZEN_SYSTEM_APPID "org.tizen.system" -GSList *proc_app_list; +struct proc_app_list app_list = { .lock = PTHREAD_MUTEX_INITIALIZER }; static GSList *proc_program_list; +GSList *proc_app_list_open(void) +{ + if (app_list.tid != gettid()) { + pthread_mutex_lock(&app_list.lock); + app_list.tid = gettid(); + } + + app_list.ref++; + + return app_list.list; +} + +void proc_app_list_close(void) +{ + int err; + + app_list.ref--; + + if (app_list.ref) + return; + + app_list.tid = 0; + + err = pthread_mutex_unlock(&app_list.lock); + if (err) + _E("Failed to unlock app list mutex: %s", + strerror(err)); +} + static bool is_ui_app(enum application_type type) { if (type == PROC_TYPE_GUI || type == PROC_TYPE_WIDGET || @@ -321,12 +360,14 @@ void proc_set_process_memory_state(struct proc_app_info *pai, */ struct proc_app_info *find_app_info_by_appid(const char *appid) { + _cleanup_app_list_close_ GSList *proc_app_list = NULL; GSList *iter = NULL; struct proc_app_info *pai; if (!appid) return NULL; + proc_app_list = proc_app_list_open(); gslist_for_each_item(iter, proc_app_list) { pai = (struct proc_app_info *)iter->data; if (equal_name_info(pai->appid, appid)) @@ -337,14 +378,19 @@ struct proc_app_info *find_app_info_by_appid(const char *appid) struct proc_app_info *find_app_info(const pid_t pid) { + _cleanup_app_list_close_ GSList *proc_app_list = NULL; GSList *iter = NULL; struct proc_app_info *pai = NULL; + proc_app_list = proc_app_list_open(); gslist_for_each_item(iter, proc_app_list) { pai = (struct proc_app_info *)iter->data; - if ((pai->main_pid == pid) || - (pai->childs && g_slist_find(pai->childs, PID_TO_GPOINTER(pid)))) + if (pai->main_pid == pid) return pai; + if (pai->childs) { + if (g_slist_find(pai->childs, PID_TO_GPOINTER(pid))) + return pai; + } } return NULL; } @@ -476,7 +522,7 @@ static int proc_runtime_write_app_info(const struct proc_app_info *pai) return -ENOMEM; ret = mkdir(runtime_app_info_path, S_IRWXU | S_IRGRP | S_IXGRP); - if (ret < 0) + if (ret && errno != EEXIST) return ret; ret = proc_runtime_app_info_write_appid(runtime_app_info_path, pai->appid); @@ -589,6 +635,7 @@ finish: struct proc_app_info *proc_add_app_list(const int type, const pid_t pid, const char *appid, const char *pkgname) { + _cleanup_app_list_close_ GSList *proc_app_list = NULL; struct proc_app_info *pai; int ret; @@ -598,6 +645,7 @@ struct proc_app_info *proc_add_app_list(const int type, const pid_t pid, /* * check lastet item firstly because app list has already created in prelaunch */ + proc_app_list = proc_app_list_open(); pai = (struct proc_app_info *)g_slist_nth_data(proc_app_list, 0); if (!pai || pai->type != PROC_TYPE_READY) { _E("not found previous pai : %s", appid); @@ -682,10 +730,12 @@ remove_all: int proc_remove_app_list(const pid_t pid) { + _cleanup_app_list_close_ GSList *proc_app_list = NULL; GSList *iter; struct proc_app_info *pai = NULL; struct proc_program_info *ppi; + proc_app_list = proc_app_list_open(); gslist_for_each_item(iter, proc_app_list) { pai = (struct proc_app_info *)iter->data; int ret; @@ -726,6 +776,7 @@ int proc_remove_app_list(const pid_t pid) struct proc_app_info *proc_create_app_list(const char *appid, const char *pkgid) { + _cleanup_app_list_close_ GSList *proc_app_list = NULL; struct proc_app_info *pai; if (!appid) return NULL; @@ -747,16 +798,20 @@ struct proc_app_info *proc_create_app_list(const char *appid, const char *pkgid) } pai->proc_exclude = resourced_proc_excluded(appid); + proc_app_list = proc_app_list_open(); proc_app_list = g_slist_prepend(proc_app_list, pai); + app_list.list = proc_app_list; return pai; } int proc_delete_all_lists(void) { + _cleanup_app_list_close_ GSList *proc_app_list = NULL; GSList *iter, *next; struct proc_app_info *pai = NULL; struct proc_program_info *ppi = NULL; + proc_app_list = proc_app_list_open(); gslist_for_each_safe(proc_app_list, iter, next, pai) { _remove_child_pids(pai, 0); ppi = pai->program; @@ -800,11 +855,13 @@ int proc_get_svc_state(struct proc_program_info *ppi) static void proc_dump_process_list(FILE *fp) { + _cleanup_app_list_close_ GSList *proc_app_list = NULL; GSList *iter, *iter_child; struct proc_app_info *pai = NULL; int index = 0, ret, oom_score_adj; LOG_DUMP(fp, "[APPLICATION LISTS]\n"); + proc_app_list = proc_app_list_open(); gslist_for_each_item(iter, proc_app_list) { char *typestr; unsigned int size; @@ -1039,6 +1096,7 @@ static void proc_module_exit(void *data) static int proc_restore_runtime_app_info(const char *path) { + _cleanup_app_list_close_ GSList *proc_app_list = NULL; _cleanup_free_ char *appid = NULL, *pkgname = NULL; struct proc_app_info *pai; int oom_score_adj = 0, ret; @@ -1062,6 +1120,7 @@ static int proc_restore_runtime_app_info(const char *path) ret = proc_get_oom_score_adj(pai->main_pid, &oom_score_adj); if (ret < 0) { _I("pid %d is already terminated. remove it", pai->main_pid); + proc_app_list = proc_app_list_open(); proc_app_list = g_slist_remove(proc_app_list, pai); resourced_appinfo_put(pai->ai); free(pai); @@ -1196,6 +1255,7 @@ int proc_get_appflag(const pid_t pid) void proc_set_group(pid_t ownerpid, pid_t childpid, char *pkgname) { + _cleanup_app_list_close_ GSList *proc_app_list = NULL; int owner_oom = 0, child_oom = 0, ret; int child_type = 0, child_state = 0; struct proc_program_info *ppi; @@ -1241,6 +1301,7 @@ void proc_set_group(pid_t ownerpid, pid_t childpid, char *pkgname) owner->categories += pai->categories; if (pai->runtime_exclude) owner->runtime_exclude += pai->runtime_exclude; + proc_app_list = proc_app_list_open(); proc_app_list = g_slist_remove(proc_app_list, pai); free(pai); } else { diff --git a/src/proc-stat/proc-monitor.c b/src/proc-stat/proc-monitor.c index 3a9d31b..66aaeb3 100644 --- a/src/proc-stat/proc-monitor.c +++ b/src/proc-stat/proc-monitor.c @@ -280,6 +280,7 @@ static DBusMessage *edbus_get_app_memory(E_DBus_Object *obj, DBusMessage *msg) static DBusMessage *edbus_get_memory_list(E_DBus_Object *obj, DBusMessage *msg) { + _cleanup_app_list_close_ GSList *proc_app_list = NULL; DBusMessageIter iter; DBusMessageIter arr; DBusMessage *reply; @@ -289,6 +290,7 @@ static DBusMessage *edbus_get_memory_list(E_DBus_Object *obj, DBusMessage *msg) unsigned int total = 0, usage = 0; reply = dbus_message_new_method_return(msg); + proc_app_list = proc_app_list_open(); gslist_for_each_item(giter, proc_app_list) { pai = (struct proc_app_info *)giter->data; if (!pai->main_pid) @@ -320,6 +322,7 @@ static DBusMessage *edbus_get_memory_list(E_DBus_Object *obj, DBusMessage *msg) static DBusMessage *edbus_get_cpu_list(E_DBus_Object *obj, DBusMessage *msg) { + _cleanup_app_list_close_ GSList *proc_app_list = NULL; DBusMessageIter iter; DBusMessageIter arr; DBusMessage *reply; @@ -339,6 +342,7 @@ static DBusMessage *edbus_get_cpu_list(E_DBus_Object *obj, DBusMessage *msg) dbus_message_iter_init_append(reply, &iter); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(su)", &arr); + proc_app_list = proc_app_list_open(); gslist_for_each_item(giter, proc_app_list) { DBusMessageIter sub; unsigned long percent; @@ -360,6 +364,7 @@ static DBusMessage *edbus_get_cpu_list(E_DBus_Object *obj, DBusMessage *msg) static DBusMessage *edbus_get_memory_lists(E_DBus_Object *obj, DBusMessage *msg) { + _cleanup_app_list_close_ GSList *proc_app_list = NULL; DBusMessageIter iter; DBusMessageIter arr; DBusMessage *reply; @@ -380,6 +385,7 @@ static DBusMessage *edbus_get_memory_lists(E_DBus_Object *obj, DBusMessage *msg) reply = dbus_message_new_method_return(msg); dbus_message_iter_init_append(reply, &iter); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(su)", &arr); + proc_app_list = proc_app_list_open(); gslist_for_each_item(giter, proc_app_list) { DBusMessageIter sub; pai = (struct proc_app_info *)giter->data; @@ -402,6 +408,7 @@ static DBusMessage *edbus_get_memory_lists(E_DBus_Object *obj, DBusMessage *msg) static DBusMessage *edbus_get_cpu_lists(E_DBus_Object *obj, DBusMessage *msg) { + _cleanup_app_list_close_ GSList *proc_app_list = NULL; DBusMessageIter iter; DBusMessageIter arr; DBusMessage *reply; @@ -429,6 +436,7 @@ static DBusMessage *edbus_get_cpu_lists(E_DBus_Object *obj, DBusMessage *msg) dbus_message_iter_init_append(reply, &iter); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(su)", &arr); + proc_app_list = proc_app_list_open(); gslist_for_each_item(giter, proc_app_list) { DBusMessageIter sub; unsigned long percent; diff --git a/src/proc-stat/proc-process.c b/src/proc-stat/proc-process.c index ba78475..c278adb 100644 --- a/src/proc-stat/proc-process.c +++ b/src/proc-stat/proc-process.c @@ -87,6 +87,7 @@ static void proc_set_oom_score_services(int state, GSList *svcs, static int proc_backgrd_manage(int currentpid, int active, int oom_score_adj) { + _cleanup_app_list_close_ GSList *proc_app_list = NULL; pid_t pid = -1; int flag = RESOURCED_NOTIFIER_APP_BACKGRD; struct proc_status ps; @@ -137,6 +138,7 @@ static int proc_backgrd_manage(int currentpid, int active, int oom_score_adj) } if (checkprevpid != currentpid) { + proc_app_list = proc_app_list_open(); gslist_for_each_item(iter, proc_app_list) { struct proc_app_info *spi = (struct proc_app_info *)iter->data; int new_oom; @@ -302,6 +304,7 @@ static Eina_Bool proc_check_sweep_cb(void *data) int proc_sweep_memory(enum proc_sweep_type type, pid_t callpid) { + _cleanup_app_list_close_ GSList *proc_app_list = NULL; pid_t pid = -1; int count = 0, ret; FILE *fp; @@ -325,6 +328,7 @@ int proc_sweep_memory(enum proc_sweep_type type, pid_t callpid) else select_sweep_limit = OOMADJ_BACKGRD_LOCKED; + proc_app_list = proc_app_list_open(); gslist_for_each_item(iter, proc_app_list) { pai = (struct proc_app_info *)iter->data; if (!pai->main_pid || pai->type != PROC_TYPE_GUI) diff --git a/src/swap/swap.c b/src/swap/swap.c index 1b2460f..947a960 100644 --- a/src/swap/swap.c +++ b/src/swap/swap.c @@ -290,6 +290,7 @@ static int swap_sort_by_vmrss(const struct swap_task *ta, static int swap_prepare_victims(GArray *candidates) { + _cleanup_app_list_close_ GSList *proc_app_list = NULL; GSList *iter = NULL; struct proc_app_info *pai = NULL; struct swap_task victim; @@ -299,6 +300,7 @@ static int swap_prepare_victims(GArray *candidates) * It was better than searching backround cgroup * because proc_app_list had already known current state and child processes */ + proc_app_list = proc_app_list_open(); gslist_for_each_item(iter, proc_app_list) { pai = (struct proc_app_info *)iter->data; if (pai->memory.memcg_idx != MEMCG_BACKGROUND) -- 2.7.4