proc-stat : create critical section for proc_app_list 03/95803/4
authorKichan Kwon <k_c.kwon@samsung.com>
Sat, 5 Nov 2016 08:55:57 +0000 (17:55 +0900)
committerKichan Kwon <k_c.kwon@samsung.com>
Mon, 7 Nov 2016 06:51:38 +0000 (15:51 +0900)
- System-freezer will link proc_app_list functions to use it

Change-Id: I57acaba1bee806e98e7f42bdf4529a892cdb7dae
Signed-off-by: Kichan Kwon <k_c.kwon@samsung.com>
src/common/proc-common.h
src/freezer/freezer.c
src/heart/heart-cpu.c
src/proc-stat/include/proc-main.h
src/proc-stat/proc-main.c
src/proc-stat/proc-monitor.c
src/proc-stat/proc-process.c
src/swap/swap.c

index ec749a5..f121390 100644 (file)
@@ -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;
index ae5b47d..a7cc79f 100644 (file)
@@ -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) {
index e892d42..6d6d870 100644 (file)
@@ -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;
index 1cb5da3..a8c0dcb 100644 (file)
 #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__ */
index d40af96..c7d037c 100644 (file)
 #include "file-helper.h"
 #include "config-parser.h"
 
+#ifndef gettid
+#include <sys/syscall.h>
+
+#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 {
index 3a9d31b..66aaeb3 100644 (file)
@@ -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;
index ba78475..c278adb 100644 (file)
@@ -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)
index 1b2460f..947a960 100644 (file)
@@ -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)