module: Refactor to use lists per priorities 63/290863/5
authorSangYoun Kwak <sy.kwak@samsung.com>
Tue, 4 Apr 2023 08:04:32 +0000 (17:04 +0900)
committerSangYoun Kwak <sy.kwak@samsung.com>
Fri, 7 Apr 2023 04:53:32 +0000 (13:53 +0900)
The 'module' feature in resourced manages the modules.
Previously, it used one list to manage modules, so it has to check the
all modules in list to find which was looking for.

In this patch, the 'module' uses separate lists per priorities.
Since the lists of modules are classified by its priority, modules with
specific priority can be found without iterating all lists.

Entries of the 'enum module_priority' are added to make it easy to
iterate through the priorities. (These values are not a priority value)
 * MODULE_PRIORITY_MIN = -1
 * MODULE_PRIORITY_MAX

Change-Id: I7d620d03f1245ed589ea3753a474895f8b232468
Signed-off-by: SangYoun Kwak <sy.kwak@samsung.com>
src/common/module/module.c
src/common/module/module.h

index 32f32f8..ce2df2c 100644 (file)
 
 #include <glib.h>
 
-static GSList *modules_list;
+#define module_iterate_all_priorities(priority) \
+       for (priority = (MODULE_PRIORITY_MAX - 1); \
+                       priority > MODULE_PRIORITY_MIN; --priority) \
+
+#define module_iterate_all_modules(priority, iter) \
+       module_iterate_all_priorities(priority) \
+               gslist_for_each_item(iter, modules_list[priority])
+
+#define module_iterate_all_modules_safe(priority, iter, next, module) \
+       module_iterate_all_priorities(priority) \
+               gslist_for_each_safe(modules_list[priority], iter, next, module)
+
+
+static GSList *modules_list[MODULE_PRIORITY_MAX];
+
+static void assert_priority(enum module_priority priority)
+{
+       switch(priority) {
+       case MODULE_PRIORITY_LATE:
+       case MODULE_PRIORITY_NORMAL:
+       case MODULE_PRIORITY_HIGH:
+       case MODULE_PRIORITY_EARLY:
+               return;
+       default:
+               _E("Invalid module priority: %d", priority);
+               assert(0);
+       }
+}
 
 void add_module(const struct module_ops *module)
 {
        ret_msg_if(!module, "Invalid module handler\n");
 
-       if (module->priority == MODULE_PRIORITY_EARLY)
-               modules_list = g_slist_prepend(modules_list, (gpointer)module);
-       else
-               modules_list = g_slist_append(modules_list, (gpointer)module);
+       enum module_priority p = module->priority;
+       assert_priority(p);
+
+       modules_list[p] = g_slist_prepend(modules_list[p], (gpointer)module);
 }
 
 void remove_module(const struct module_ops *module)
 {
-       modules_list = g_slist_remove(modules_list, (gpointer)module);
+       ret_msg_if(!module, "Invalid module handler\n");
+
+       enum module_priority p = module->priority;
+       assert_priority(p);
+
+       modules_list[p] = g_slist_remove(modules_list[p], (gpointer)module);
 }
 
 const struct module_ops *find_module(const char *name)
 {
        GSList *iter;
        const struct module_ops *module;
+       int priority;
 
-       gslist_for_each_item(iter, modules_list) {
+       module_iterate_all_modules(priority, iter) {
                module = (struct module_ops *)iter->data;
-               if (!strncmp(module->name, name, strlen(module->name) + 1) &&
-                  (module->initalized == MODULE_INITIALIZED))
-                       return module;
+               if (module->initalized != MODULE_INITIALIZED)
+                       continue;
+               if (strncmp(module->name, name, strlen(module->name) + 1) != 0)
+                       continue;
+               return module;
        }
+
        return NULL;
 }
 
@@ -65,10 +101,9 @@ void modules_check_runtime_support(void UNUSED *data)
 {
        GSList *iter, *next;
        const struct module_ops *module;
-       int ret;
+       int priority, ret;
 
-       gslist_for_each_safe(modules_list, iter, next, module) {
-               module = (const struct module_ops *)iter->data;
+       module_iterate_all_modules_safe(priority, iter, next, module) {
                _D("check runtime support [%s] module\n", module->name);
 
                if (!module->check_runtime_support)
@@ -83,20 +118,18 @@ void modules_check_runtime_support(void UNUSED *data)
        }
 }
 
-static void module_initcall_level(void *data, int priority)
+static void module_init_per_priority(void *data, enum module_priority priority)
 {
        GSList *iter;
        struct module_ops *module;
        int ret;
 
-       gslist_for_each_item(iter, modules_list) {
-               module = (struct module_ops *)iter->data;
+       assert_priority(priority);
 
+       gslist_for_each_item(iter, modules_list[priority]) {
+               module = (struct module_ops *)iter->data;
                assert(module);
 
-               if (module->priority < priority)
-                       continue;
-
                if (module->initalized != MODULE_NONINITIALIZED)
                        continue;
 
@@ -117,13 +150,16 @@ static void module_initcall_level(void *data, int priority)
 
 void modules_init(void *data)
 {
-       module_initcall_level(data, MODULE_PRIORITY_HIGH);
+       module_init_per_priority(data, MODULE_PRIORITY_EARLY);
+       module_init_per_priority(data, MODULE_PRIORITY_HIGH);
 }
 
 void modules_init_late(void *data)
 {
-       module_initcall_level(data, MODULE_PRIORITY_NORMAL);
-       module_initcall_level(data, MODULE_PRIORITY_LATE);
+       module_init_per_priority(data, MODULE_PRIORITY_EARLY);
+       module_init_per_priority(data, MODULE_PRIORITY_HIGH);
+       module_init_per_priority(data, MODULE_PRIORITY_NORMAL);
+       module_init_per_priority(data, MODULE_PRIORITY_LATE);
 }
 
 void modules_exit(void *data)
@@ -131,29 +167,35 @@ void modules_exit(void *data)
        GSList *iter;
        struct module_ops *module;
        int ret;
+       int priority;
 
-       gslist_for_each_item(iter, modules_list) {
+       module_iterate_all_modules(priority, iter) {
                module = (struct module_ops *)iter->data;
                if (module->exit && (module->initalized == MODULE_INITIALIZED)) {
                        module->initalized = MODULE_NONINITIALIZED;
                        ret = module->exit(data);
-                       if (ret < 0)
+                       if (ret < 0) {
                                _E("Fail to deinitialize [%s] module\n", module->name);
-                       else
-                               _D("Deinitialize [%s] module\n", module->name);
+                               continue;
+                       }
+                       _D("Deinitialize [%s] module\n", module->name);
                }
        }
-       g_slist_free(modules_list);
-       modules_list = NULL;
+
+       module_iterate_all_priorities(priority) {
+               g_slist_free(modules_list[priority]);
+               modules_list[priority] = NULL;
+       }
 }
 
 void modules_restore(void *data)
 {
-       struct module_ops *module;
        GSList *iter;
+       struct module_ops *module;
        int ret;
+       int priority;
 
-       gslist_for_each_item(iter, modules_list) {
+       module_iterate_all_modules(priority, iter) {
                module = (struct module_ops *)iter->data;
 
                assert(module);
@@ -178,15 +220,18 @@ void modules_dump(FILE *fp, int mode)
 {
        GSList *iter;
        const struct module_ops *module;
+       int priority;
 
-       gslist_for_each_item(iter, modules_list) {
+       module_iterate_all_modules(priority, iter) {
                module = (struct module_ops *)iter->data;
                if (module->initalized != MODULE_INITIALIZED)
                        continue;
 
+               if (!module->dump)
+                       continue;
+
                _D("dump [%s] module\n", module->name);
-               if (module->dump)
-                       module->dump(fp, mode, module->dump_data);
+               module->dump(fp, mode, module->dump_data);
        }
 }
 
@@ -195,11 +240,12 @@ static void dbus_list_active_modules_handler(GDBusMethodInvocation *invocation,
        struct module_ops *module;
        GSList *list_iter;
        GVariantBuilder builder, *sub_builder;
+       int priority;
 
        g_variant_builder_init(&builder, G_VARIANT_TYPE_TUPLE);
        sub_builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
 
-       gslist_for_each_item(list_iter, modules_list) {
+       module_iterate_all_modules(priority, list_iter) {
                module = (struct module_ops *)list_iter->data;
                if (module->initalized != MODULE_INITIALIZED)
                        continue;
index 0cf1aa0..c66b7b9 100644 (file)
@@ -34,30 +34,16 @@ extern "C" {
  * modules.
  */
 enum module_priority {
-       /**
-        * MODULE_PRIORITY_LATE is default priority of modules.
-        * These modules are initialized after other modules
-        * are initialized.
-        */
-       MODULE_PRIORITY_LATE = 0,
+       MODULE_PRIORITY_MIN = -1,       /* indicates the start of priority */
+                                       /* Don't use MODULE_PRIORITY_MIN as a priority */
 
-       /**
-        * MODULE_PRIORITY_NORMAL modules are initialized after
-        * booting is done.
-        */
-       MODULE_PRIORITY_NORMAL,
+       MODULE_PRIORITY_LATE = 0,       /* Default priority */
+       MODULE_PRIORITY_NORMAL,         /* Initialized after booting is done */
+       MODULE_PRIORITY_HIGH,           /* Initialized as soon as resourced is started */
+       MODULE_PRIORITY_EARLY,          /* initialized before NORMAL priority modules */
 
-       /**
-        * MODULE_PRIORITY_HIGH modules are initialized
-        * as soon as resourced is started.
-        */
-       MODULE_PRIORITY_HIGH,
-
-       /**
-        * MODULE_PRIORITY_EARLY modules are initialized
-        * before MODULE_PRIORITY_NORMAL modules.
-        */
-       MODULE_PRIORITY_EARLY,
+       MODULE_PRIORITY_MAX,            /* indicates the number of priorities*/
+                                       /* Don't use MODULE_PRIORITY_MAX as a priority */
 };
 
 enum module_state {