util: resource: Add resource management 83/269983/6
authorDongwoo Lee <dwoo08.lee@samsung.com>
Tue, 18 Jan 2022 06:32:00 +0000 (15:32 +0900)
committerChanwoo Choi <cw00.choi@samsung.com>
Mon, 24 Jan 2022 09:23:58 +0000 (18:23 +0900)
Resource Manager provides the template and then each resource
is able to make the their own resource driver under src/resource
directory. Also, each resoruce is able to have the multiple attributes
such as min frequency of CPU, max frequency of CPU, available memory of
Memory and so on. Lastly, each attribute must define the their onw data
type like integer, double, string and so on.

[Example of resource and attribue, data type]
resource A
- attribute A1 with data type
- attribute A2 with data type
resource B
- attribute B1 with data type
- attribute B2 with data type
- attribute B3 with data type
resource C
...
resource D
...

[Newly added functions for resource manager]
- Add/Remove resource driver like resource-cpu.c. resource-memory.c
void add_resource_driver(const struct resource_driver *resource_driver);
void remove_resource_driver(const struct resource_driver *resource_driver);

- Create/Delete resource instance like CPU/BUS/GPU/Battery/Memory/Proc
struct resource *create_resource(int resource_type, char *resource_name);
void delete_resource(struct resource *resource);

- Update the attribute values of each resource
int update_resource_attr(struct resource *resource, int attr_id);
int update_resource_attrs(struct resource *resource);

- Get the attribute values of specific attribute
struct resource_attribute_value *get_resource_attr_value(struct resource *resource, int attr_id);
int get_resource_attr_integer(struct resource *resource, int attr_id);
int get_resource_attr_integer_sync(struct resource *resource, int attr_id);

Change-Id: I45e7ef3e6c8138b49063dd9fc6e84dd8b9448c0a
Signed-off-by: Dongwoo Lee <dwoo08.lee@samsung.com>
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
CMakeLists.txt
include/util/resource.h [new file with mode: 0644]
src/util/resource.c [new file with mode: 0644]

index c9af4c3..76e647d 100644 (file)
@@ -27,6 +27,7 @@ SET(SRCS
        src/util/common.c
        src/util/device-notifier.c
        src/util/devices.c
+       src/util/resource.c
        src/util/gdbus-util.c
        src/main.c
        #Generated by a custom command 'gdbus-codegen' below
diff --git a/include/util/resource.h b/include/util/resource.h
new file mode 100644 (file)
index 0000000..09ba985
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * PASS
+ *
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __RESOURCE_H__
+#define __RESOURCE_H__
+
+#include <errno.h>
+#include <glib.h>
+#include "common.h"
+
+struct resource;
+struct resource_attribute;
+
+struct resource_attribute_value {
+       /* Indicate the data type among three types (int/double/str)*/
+       int type;
+
+       union {
+               /* Have to use only one among the types */
+               int int_value;
+
+               int number_int;
+               int *int_values;
+
+               double double_value;
+
+               int number_string;
+               char *str_value;;
+       } data;
+};
+
+struct resource_attribute_ops {
+       int (*set)(const struct resource *res,
+                  const struct resource_attribute *attr,
+                  const char *buf, int count, void *user_data);
+       int (*get)(const struct resource *res,
+                  const struct resource_attribute *attr,
+                  char *buf, void *user_data);
+};
+
+struct resource_attribute {
+       const char name[BUFF_MAX];
+       const uint32 id;
+       const int type;
+       const struct resource_attribute_ops ops;
+};
+
+struct resource_driver {
+       const char *name;
+       const int type;
+       const int num_attrs;
+       const struct resource_attribute *attrs;
+};
+
+struct resource {
+       char *name;
+       int type;
+       void *user_data;
+
+       int num_attrs;
+       const struct resource_attribute *attrs;
+       struct resource_attribute_value *attrs_value;
+};
+
+#define RESOURCE_DRIVER_REGISTER(resource_driver)      \
+static void __CONSTRUCTOR__ module_init(void)  \
+{      \
+       add_resource_driver(resource_driver);   \
+}      \
+static void __DESTRUCTOR__ module_exit(void)   \
+{      \
+       remove_resource_driver(resource_driver);        \
+}
+
+void add_resource_driver(const struct resource_driver *resource_driver);
+void remove_resource_driver(const struct resource_driver *resource_driver);
+
+struct resource *create_resource(int resource_type, const char *resource_name, void *user_data);
+void delete_resource(struct resource *resource);
+
+int update_resource_attr(struct resource *resource, int attr_id);
+int update_resource_attrs(struct resource *resource);
+struct resource_attribute_value *get_resource_attr_value(struct resource *resource, int attr_id);
+int get_resource_attr_integer(struct resource *resource, int attr_id);
+int get_resource_attr_integer_sync(struct resource *resource, int attr_id);
+
+#endif
diff --git a/src/util/resource.c b/src/util/resource.c
new file mode 100644 (file)
index 0000000..846fa43
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * PASS (Power Aware System Service)
+ *
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <glib.h>
+#include <stdio.h>
+
+#include <util/common.h>
+#include <util/resource.h>
+#include <util/log.h>
+
+#include <monitor/monitor.h>
+
+static GList *g_resource_driver_head;
+
+static gint __compare_resource_type(gconstpointer data, gconstpointer input)
+{
+       struct resource_driver *driver = (struct resource_driver *)data;
+       int type = *(int *)input;
+
+       if (driver->type == type)
+               return 0;
+       return -1;
+}
+
+void add_resource_driver(const struct resource_driver *driver)
+{
+       if (!driver)
+               return;
+
+       g_resource_driver_head =
+                       g_list_append(g_resource_driver_head, (gpointer)driver);
+}
+
+void remove_resource_driver(const struct resource_driver *driver)
+{
+       if (!driver)
+               return;
+
+       g_resource_driver_head =
+                       g_list_remove(g_resource_driver_head, (gpointer)driver);
+}
+
+const struct resource_driver *get_resource_driver(int resource_type)
+{
+       GList *node;
+
+       node = g_list_find_custom(g_resource_driver_head,
+                       &resource_type, __compare_resource_type);
+
+       if (!node)
+               return NULL;
+       return (struct resource_driver *)node->data;
+}
+
+void delete_resource(struct resource *resource)
+{
+       if (!resource)
+               return;
+
+       if (!resource->name)
+               free(resource->name);
+       if (!resource->attrs_value)
+               free(resource->attrs_value);
+       resource->attrs = NULL;
+       resource->num_attrs = 0;
+
+       free(resource);
+}
+
+struct resource *create_resource(int resource_type, const char *resource_name, void *user_data)
+{
+       const struct resource_driver *driver = NULL;
+       struct resource *resource = NULL;
+       int i;
+
+       driver = get_resource_driver(resource_type);
+       if (!driver)
+               return NULL;
+
+       resource = calloc(1, sizeof(*resource));
+       if (!resource)
+               return NULL;
+
+       resource->type = resource_type;
+       resource->name = g_strdup(resource_name);
+       resource->user_data = user_data;
+       resource->num_attrs = driver->num_attrs;
+       resource->attrs = driver->attrs;
+       resource->attrs_value = calloc(resource->num_attrs,
+                                       sizeof(*resource->attrs_value));
+       if (!resource->attrs_value) {
+               delete_resource(resource);
+               return NULL;
+       }
+
+       for (i = 0; i < resource->num_attrs; i++)
+               resource->attrs_value[i].type = driver->attrs[i].type;
+
+       return resource;
+}
+
+int update_resource_attr(struct resource *resource, int attr_id)
+{
+       int resource_type = RESOURCE_TYPE(attr_id);
+       int attr_index = RESOURCE_ATTR_INDEX(attr_id);
+       const struct resource_attribute *attr = NULL;
+       struct resource_attribute_value *attr_value = NULL;
+       char buf[BUFF_MAX];
+       int ret;
+
+       if (!resource || resource->type != resource_type)
+               return -EINVAL;
+
+       if (attr_index < 0 || attr_index >= resource->num_attrs)
+               return -EINVAL;
+
+       attr = &resource->attrs[attr_index];
+       attr_value = &resource->attrs_value[attr_index];
+
+       if (!attr->ops.get)
+               return -EINVAL;
+
+       ret = attr->ops.get(resource, attr, buf, resource->user_data);
+       if (ret < 0)
+               return ret;
+
+       /* FIXME: Need to be changed according to data type*/
+       ret = sscanf(buf, "%d", &(attr_value->data.int_value));
+       if (ret != 1)
+               return -EINVAL;
+
+       return 0;
+}
+
+int update_resource_attrs(struct resource *resource)
+{
+       int i, ret;
+
+       if (!resource || !resource->type)
+               return -EINVAL;
+
+       for (i = 0; i < resource->num_attrs; i++) {
+               ret = update_resource_attr(resource, resource->attrs[i].id);
+               if (ret < 0) {
+                       _E("failed to update resource attr \n");
+               }
+       }
+
+       return 0;
+}
+
+struct resource_attribute_value *
+get_resource_attr_value(struct resource *resource, int attr_id)
+{
+       int attr_index = RESOURCE_ATTR_INDEX(attr_id);
+
+       if (!resource || resource->type != RESOURCE_TYPE(attr_id))
+               return NULL;
+
+       if (!resource || attr_index < 0 || attr_index >= resource->num_attrs)
+               return NULL;
+
+       return &resource->attrs_value[attr_index];
+}
+
+int get_resource_attr_integer(struct resource *resource, int attr_id)
+{
+       struct resource_attribute_value *attr_value =
+                               get_resource_attr_value(resource, attr_id);
+
+       if (!attr_value)
+               return -EINVAL;
+
+       return attr_value->data.int_value;
+}
+
+int get_resource_attr_integer_sync(struct resource *resource, int attr_id)
+{
+       int ret;
+
+       ret = update_resource_attr(resource, attr_id);
+       if (ret < 0)
+               return ret;
+
+       return get_resource_attr_integer(resource, attr_id);
+}