core: Modify device notifier registering/unregistering mechanism 83/129883/4
authorWook Song <wook16.song@samsung.com>
Thu, 18 May 2017 08:07:37 +0000 (17:07 +0900)
committerWook Song <wook16.song@samsung.com>
Fri, 9 Jun 2017 01:26:41 +0000 (01:26 +0000)
This patch modifies the registering and unregistering mechanism of
device_notifier to use a static array instead of dynamically allocated
memory. A bug in the unregister_notifier function is also fixed. Since
the prototype of the function is changed, all locations where this
function is called are also slightly modified.

Change-Id: Iac5afc5f5c283f277220ac49d173bf420e3fb4ee
Signed-off-by: Wook Song <wook16.song@samsung.com>
Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
src/core/device-notifier.c
src/core/device-notifier.h
src/core/udev.c
src/pass/pass-gov.c
src/pass/pass.c
src/pmqos/pmqos.c

index 1195d0c0992e3b2b1ccfc3ae7c59a5944752a19f..7588281d26f667455f67e4a10788b537e60196e8 100644 (file)
 #include "list.h"
 #include "common.h"
 
-struct device_notifier {
-       bool deleted;
-       enum device_notifier_type status;
-       int (*func)(void *data, void *user_data);
-       void *user_data;
-};
+#define DEVICE_NOTIFIER_MAX_COUNT      255
 
 static dd_list *device_notifier_list;
 static Ecore_Idler *idl;
+static struct device_notifier device_notifiers[DEVICE_NOTIFIER_MAX_COUNT];
+
+#define FIND_NOTIFIER(a, b, c, d, e, f) \
+       DD_LIST_FOREACH(a, b, c) \
+               if (d == c->d && e == (c->e) && f == (c->f))
+
+static struct device_notifier *get_device_notifier(void) {
+       static int pos = 0;
+
+       if ((pos < DEVICE_NOTIFIER_MAX_COUNT) &&
+               (!device_notifiers[pos].is_used)) {
+               device_notifiers[pos].is_used = true;
+               return &device_notifiers[pos++];
+       } else {
+               for (pos = 0; pos < DEVICE_NOTIFIER_MAX_COUNT; pos++) {
+                       if (!device_notifiers[pos].is_used) {
+                               device_notifiers[pos].is_used = true;
+                               return &device_notifiers[pos];
+                       }
+               }
+       }
 
-#define FIND_NOTIFIER(a, b, d, e, f) \
-       DD_LIST_FOREACH(a, b, d) \
-               if (e == d->e && f == (d->f))
+       return NULL;
+}
 
 int register_notifier(enum device_notifier_type status,
                int (*func)(void *data, void *user_data), void *user_data)
 {
        struct device_notifier *notifier;
 
-       if (!func) {
-               _E("invalid func address!");
+       if (status >= DEVICE_NOTIFIER_MAX)
+               return -EINVAL;
+
+       if (!func)
                return -EINVAL;
-       }
 
-       notifier = calloc(1, sizeof(struct device_notifier));
-       if (!notifier) {
-               _E("Fail to malloc for notifier!");
+       notifier = get_device_notifier();
+       if (!notifier)
                return -ENOMEM;
-       }
 
        notifier->status = status;
        notifier->func = func;
@@ -62,19 +76,14 @@ int register_notifier(enum device_notifier_type status,
 }
 
 int unregister_notifier(enum device_notifier_type status,
-               int (*func)(void *data, void *user_data))
+               int (*func)(void *data, void *user_data), void *user_data)
 {
        dd_list *n;
        struct device_notifier *notifier;
 
-       if (!func) {
-               _E("invalid func address!");
-               return -EINVAL;
-       }
-
-       FIND_NOTIFIER(device_notifier_list, n, notifier, status, func) {
-               _I("[%d, %x]", status, func);
-               notifier->deleted = true;
+       FIND_NOTIFIER(device_notifier_list, n, notifier, status, func,
+                       user_data) {
+               notifier->is_used = false;
        }
 
        return 0;
@@ -87,9 +96,9 @@ static Eina_Bool delete_unused_notifier_cb(void *data)
        struct device_notifier *notifier;
 
        DD_LIST_FOREACH_SAFE(device_notifier_list, n, next, notifier) {
-               if (notifier->deleted) {
+               if (!notifier->is_used) {
+                       memset(notifier, 0, sizeof(*notifier));
                        DD_LIST_REMOVE_LIST(device_notifier_list, n);
-                       free(notifier);
                }
        }
 
@@ -103,7 +112,7 @@ void device_notify(enum device_notifier_type status, void *data)
        struct device_notifier *notifier;
 
        DD_LIST_FOREACH(device_notifier_list, n, notifier) {
-               if (!notifier->deleted && status == notifier->status) {
+               if (notifier->is_used && status == notifier->status) {
                        if (notifier->func)
                                notifier->func(data, notifier->user_data);
                }
index 9ae29be53a9da7e92739340ca7553ccfab8bd819..77c571f7802228edd8288abbddfa4835b1d20bb0 100644 (file)
@@ -20,6 +20,8 @@
 #ifndef __DEVICE_NOTIFIER_H__
 #define __DEVICE_NOTIFIER_H__
 
+#include <stdbool.h>
+
 enum device_notifier_type {
        DEVICE_NOTIFIER_BOOTING_DONE,
        DEVICE_NOTIFIER_PMQOS,
@@ -27,13 +29,20 @@ enum device_notifier_type {
        DEVICE_NOTIFIER_MAX,
 };
 
+struct device_notifier {
+       bool is_used;
+       enum device_notifier_type status;
+       int (*func)(void *data, void *user_data);
+       void *user_data;
+};
+
 /*
  * This is for internal callback method.
  */
 int register_notifier(enum device_notifier_type status,
                int (*func)(void *data, void *user_data), void *user_data);
 int unregister_notifier(enum device_notifier_type status,
-               int (*func)(void *data, void *user_data));
+               int (*func)(void *data, void *user_data), void *user_data);
 void device_notify(enum device_notifier_type status, void *value);
 
 #endif /* __DEVICE_NOTIFIER_H__ */
index 39e49d9febf4abd611c6368f013cc5fbeae0fde6..3e8defff7c8c9521e37271079c512e7074db62e2 100644 (file)
@@ -328,8 +328,11 @@ static void udev_init(void *data)
 {
        int ret;
 
-       register_notifier(DEVICE_NOTIFIER_POWEROFF, device_change_poweroff,
-                       NULL);
+       ret = register_notifier(DEVICE_NOTIFIER_POWEROFF,
+                       device_change_poweroff, NULL);
+       if (ret < 0)
+               _E("cannot register power-off notifier for the udev (%d)\n",
+                               ret);
 
        ret = register_edbus_method(PASS_PATH_SYSNOTI,
                        edbus_methods, ARRAY_SIZE(edbus_methods));
@@ -345,7 +348,8 @@ static void udev_init(void *data)
 
 static void udev_exit(void *data)
 {
-       unregister_notifier(DEVICE_NOTIFIER_POWEROFF, device_change_poweroff);
+       unregister_notifier(DEVICE_NOTIFIER_POWEROFF,
+                       device_change_poweroff, NULL);
 }
 
 static const struct device_ops udev_device_ops = {
index 0decd8b96967294b76f5393328519575a7db7063..13f16a292f75aca21e3463e208dad0c6ab63c69d 100644 (file)
@@ -71,9 +71,8 @@ static int pass_notifier_pmqos(void *data, void *user_data)
 static int pass_notifier_init(struct pass_policy *policy)
 {
        /* Register DEVICE_NOTIFIER_PMQOS */
-       register_notifier(DEVICE_NOTIFIER_PMQOS, pass_notifier_pmqos, policy);
-
-       return 0;
+       return register_notifier(DEVICE_NOTIFIER_PMQOS, pass_notifier_pmqos,
+                       policy);
 }
 
 /*
@@ -83,7 +82,8 @@ static int pass_notifier_init(struct pass_policy *policy)
 static int pass_notifier_exit(struct pass_policy *policy)
 {
        /* Un-register DEVICE_NOTIFIER_PMQOS */
-       unregister_notifier(DEVICE_NOTIFIER_PMQOS, pass_notifier_pmqos);
+       unregister_notifier(DEVICE_NOTIFIER_PMQOS, pass_notifier_pmqos,
+                       policy);
 
        return 0;
 }
@@ -500,6 +500,7 @@ static int __pass_governor_init(struct pass_policy *policy)
 {
        struct pass_resource *res = to_pass_resource(policy);
        struct pass_conf_data *cdata = &res->cdata;
+       int ret;
 
        if(policy->gov_timeout < 0) {
                _E("invalid timeout value [%d]!", policy->gov_timeout);
@@ -509,7 +510,11 @@ static int __pass_governor_init(struct pass_policy *policy)
 
        /* Set default PASS state */
        policy->gov_state = PASS_GOV_STOP;
-       pass_notifier_init(policy);
+       ret = pass_notifier_init(policy);
+       if (ret < 0) {
+               _E("cannot initialize notifier for the pmqos (%d)\n", ret);
+               return ret;
+       }
 
        _I("Initialize governor for '%s' resource", cdata->res_name);
 
index 33e08f38b6b7cd831aa27296ed5f0812e14b44ae..4500f615da9312966fd912f3c1b92ddb59822082 100644 (file)
@@ -308,7 +308,8 @@ static void pass_exit(void *data)
 {
        int ret;
 
-       unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, pass_init_done);
+       unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE,
+                       pass_init_done, NULL);
 
        ret = pass_exit_done();
        if (ret < 0) {
@@ -348,8 +349,8 @@ static int pass_probe(void *data)
        ret = register_notifier(DEVICE_NOTIFIER_BOOTING_DONE,
                        pass_init_done, NULL);
        if (ret < 0) {
-               _E("cannot register a callback function \
-                               for the booting-done event (%d)\n", ret);
+               _E("cannot register booting-done notifier for the pass (%d)\n",
+                               ret);
                return ret;
        }
 
index 1caa7bbcde1c3bd85bf836a427720a7b4954aa07..f6a4db491289269d410c2e15c62202bf1409077f 100644 (file)
@@ -535,7 +535,8 @@ static void pmqos_free(void)
 
 static void pmqos_exit(void *data)
 {
-       unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, pmqos_init_done);
+       unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE,
+                       pmqos_init_done, NULL);
        pmqos_free();
 }