From 412f5a5dcc85537d663de0728bb0deecb7229d27 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Fri, 4 Feb 2022 12:28:08 +0900 Subject: [PATCH 01/16] util: resource: Check data type is integer or not when getting value Each resource_attribute has the only one data type like integer, string and so on. When using the getter function for specific data type such as get_resource_attr_integer(), must need to check the data type of resource attribute. Change-Id: I868c31011d61efe05ae8a72966db462370408977 Signed-off-by: Chanwoo Choi --- include/util/resource.h | 2 ++ src/util/resource.c | 21 +++++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/include/util/resource.h b/include/util/resource.h index 49d7f45..21f22de 100644 --- a/include/util/resource.h +++ b/include/util/resource.h @@ -97,6 +97,8 @@ void delete_resource(struct resource *resource); int update_resource_attr(struct resource *resource, u_int64_t attr_id); int update_resource_attrs(struct resource *resource); int update_resource_attrs_interest(struct resource *resource, u_int64_t attr_interest_mask); + +const struct resource_attribute *get_resource_attr(struct resource *resource, u_int64_t attr_id); struct resource_attribute_value * get_resource_attr_value(struct resource *resource, u_int64_t attr_id); int get_resource_attr_integer(struct resource *resource, u_int64_t attr_id); diff --git a/src/util/resource.c b/src/util/resource.c index f164593..fad00aa 100644 --- a/src/util/resource.c +++ b/src/util/resource.c @@ -167,6 +167,17 @@ int update_resource_attrs(struct resource *resource) return update_resource_attrs_interest(resource, RESOURCE_ATTR_MASK); } +const struct resource_attribute * +get_resource_attr(struct resource *resource, u_int64_t attr_id) +{ + int attr_index = RESOURCE_ATTR_INDEX(attr_id); + + if (!resource || attr_index < 0 || attr_index >= resource->num_attrs) + return NULL; + + return &resource->attrs[attr_index]; +} + struct resource_attribute_value * get_resource_attr_value(struct resource *resource, u_int64_t attr_id) { @@ -180,9 +191,15 @@ get_resource_attr_value(struct resource *resource, u_int64_t attr_id) int get_resource_attr_integer(struct resource *resource, u_int64_t attr_id) { - struct resource_attribute_value *attr_value = - get_resource_attr_value(resource, attr_id); + const struct resource_attribute *attr = NULL; + struct resource_attribute_value *attr_value = NULL; + + /* Check whether the data type is integer or not */ + attr = get_resource_attr(resource, attr_id); + if (!attr || attr->type != DATA_TYPE_INT) + return -EINVAL; + attr_value = get_resource_attr_value(resource, attr_id); if (!attr_value) return -EINVAL; -- 2.7.4 From 7f0b325a53b5d562374ef420b3e4357dd1f63e11 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Fri, 4 Feb 2022 12:44:59 +0900 Subject: [PATCH 02/16] pass: Move pass.pc.in into packaging and remove unused files Move pass.pc.in into packaging directory and commit 469051e30f820 ("pass: hal: Replace HAL interface with hal-api-power") has removed the pass-hal-devel package. But, pass-hal-devel.pc.in/.manifest files were not removed. Remove unused pass-hal-devel related files. Change-Id: I7d568a8389c35c5d76064fbb844e76bb65a06a52 Signed-off-by: Chanwoo Choi --- CMakeLists.txt | 6 ++++-- packaging/pass-hal-devel.manifest | 5 ----- pass.pc.in => packaging/pass.pc.in | 0 pass-hal-devel.pc.in | 13 ------------- 4 files changed, 4 insertions(+), 20 deletions(-) delete mode 100644 packaging/pass-hal-devel.manifest rename pass.pc.in => packaging/pass.pc.in (100%) delete mode 100644 pass-hal-devel.pc.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 686a478..1ed88d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -111,8 +111,10 @@ CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/systemd/${PROJECT_NAME}.service.in ${CMAKE_SO INSTALL(FILES ${CMAKE_SOURCE_DIR}/systemd/org.tizen.system.pass.service DESTINATION /usr/share/dbus-1/system-services) INSTALL(FILES ${CMAKE_SOURCE_DIR}/systemd/org.tizen.system.thermal.service DESTINATION /usr/share/dbus-1/system-services) -CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY) -INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/packaging/${PROJECT_NAME}.pc.in + ${CMAKE_CURRENT_SOURCE_DIR}/packaging/${PROJECT_NAME}.pc + @ONLY) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/packaging/${PROJECT_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/systemd/ DESTINATION lib/systemd/system FILES_MATCHING diff --git a/packaging/pass-hal-devel.manifest b/packaging/pass-hal-devel.manifest deleted file mode 100644 index 97e8c31..0000000 --- a/packaging/pass-hal-devel.manifest +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/pass.pc.in b/packaging/pass.pc.in similarity index 100% rename from pass.pc.in rename to packaging/pass.pc.in diff --git a/pass-hal-devel.pc.in b/pass-hal-devel.pc.in deleted file mode 100644 index 16fcdfc..0000000 --- a/pass-hal-devel.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -# Package Information for pkg-config - -package_name=pass-hal-devel -prefix=@PREFIX@ -exec_prefix=@EXEC_PREFIX@ -libdir=@LIB_INSTALL_DIR@ -includedir=@INCLUDEDIR@ - -Name: ${package_name} -Description: -- -Version: @VERSION@ -Requires: -Cflags: -I${includedir} -- 2.7.4 From 6e4f2dc2a25acb73c2596da7a6d2b8888966555a Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Fri, 4 Feb 2022 13:21:17 +0900 Subject: [PATCH 03/16] lib: tmonitor: Add libpass skeleton package for Tizen Monitor (tmonitor) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Add libpass skelegon packages which contains the shared library and header files. Initial version just contains the Tizen Monitor's shared library and header file. But it just defines the tmonitor interface without any detailed implementation. It shold be implemnted. [Newlyd Added Packages] - libpass-1.2.0-1.aarch64.rpm - libpass-debuginfo-1.2.0-1.aarch64.rpm - libpass-devel-1.2.0-1.aarch64.rpm [File Hierarchy] └── usr ├── include │   └── pass │   └── tmonitor.h ├── lib │   └── debug │   └── usr │   └── lib64 │   └── libpass.so.0.1.0.debug ├── lib64 │   ├── libpass.so -> libpass.so.0 │   ├── libpass.so.0 -> libpass.so.0.1.0 │   ├── libpass.so.0.1.0 │   └── pkgconfig │   └── pass.pc └── share └── licenses └── libpass └── LICENSE Change-Id: I28d0e07e70db80471b50e749991f375267c8a0cb Signed-off-by: Chanwoo Choi --- CMakeLists.txt | 7 +- include/monitor/monitor-internal.h | 82 -------------------- include/util/resource.h | 10 +++ lib/CMakeLists.txt | 49 ++++++++++++ lib/tmonitor/tmonitor.c | 90 ++++++++++++++++++++++ lib/tmonitor/tmonitor.h | 151 +++++++++++++++++++++++++++++++++++++ packaging/pass.spec | 28 +++++++ src/resource/resource-bus.c | 4 +- src/resource/resource-cpu.c | 4 +- src/resource/resource-gpu.c | 4 +- src/resource/resource-memory.c | 4 +- src/util/resource.c | 3 +- 12 files changed, 340 insertions(+), 96 deletions(-) delete mode 100644 include/monitor/monitor-internal.h create mode 100644 lib/CMakeLists.txt create mode 100644 lib/tmonitor/tmonitor.c create mode 100644 lib/tmonitor/tmonitor.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ed88d1..568afd4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,7 @@ SET(SRCS INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/lib) SET(PKG_MODULES dlog @@ -111,14 +112,10 @@ CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/systemd/${PROJECT_NAME}.service.in ${CMAKE_SO INSTALL(FILES ${CMAKE_SOURCE_DIR}/systemd/org.tizen.system.pass.service DESTINATION /usr/share/dbus-1/system-services) INSTALL(FILES ${CMAKE_SOURCE_DIR}/systemd/org.tizen.system.thermal.service DESTINATION /usr/share/dbus-1/system-services) -CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/packaging/${PROJECT_NAME}.pc.in - ${CMAKE_CURRENT_SOURCE_DIR}/packaging/${PROJECT_NAME}.pc - @ONLY) -INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/packaging/${PROJECT_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) - INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/systemd/ DESTINATION lib/systemd/system FILES_MATCHING PATTERN "*.service" ) ADD_SUBDIRECTORY(unittest) +ADD_SUBDIRECTORY(lib) diff --git a/include/monitor/monitor-internal.h b/include/monitor/monitor-internal.h deleted file mode 100644 index f5afbfb..0000000 --- a/include/monitor/monitor-internal.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * PASS (Power Aware System Service) - Header file of Unified Resource Monitor - * - * 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. - */ - -/** - * @file monitor.h - * @brief Define the data structure for Unified Resource Monitor - * @ingroup COM_POWER_MGNT - */ - -#include - -#ifndef __MONITOR_INTERNAL__ -#define __MONITOR_INTERNAL__ - -#define BIT(x) (1ULL << x) -#define RESOURCE_ATTR_MASK (ULLONG_MAX) -#define RESOURCE_ATTR_INDEX(id) (63 - __builtin_clzll(id)) - -enum monitor_data_type { - DATA_TYPE_UNKNOWN = 0, - DATA_TYPE_INT, - DATA_TYPE_DOUBLE, - DATA_TYPE_STRING, - DATA_TYPE_ARRAY, - - DATA_TYPE_NUM -}; - -/* CPU attributes */ -#define CPU_CUR_FREQ BIT(0) -#define CPU_MIN_FREQ BIT(1) -#define CPU_MAX_FREQ BIT(2) -#define CPU_AVAILABLE_MIN_FREQ BIT(3) -#define CPU_AVAILABLE_MAX_FREQ BIT(4) -#define CPU_CUR_GOVERNOR BIT(5) -#define CPU_ONLINE_CPU BIT(6) -#define CPU_TEMPERATURE BIT(7) - -/* BUS attributes */ -#define BUS_CUR_FREQ BIT(0) -#define BUS_MIN_FREQ BIT(1) -#define BUS_MAX_FREQ BIT(2) -#define BUS_AVAILABLE_MIN_FREQ BIT(3) -#define BUS_AVAILABLE_MAX_FREQ BIT(4) -#define BUS_CUR_GOVERNOR BIT(5) - -/* GPU attributes */ -#define GPU_CUR_FREQ BIT(0) -#define GPU_MIN_FREQ BIT(1) -#define GPU_MAX_FREQ BIT(2) -#define GPU_AVAILABLE_MIN_FREQ BIT(3) -#define GPU_AVAILABLE_MAX_FREQ BIT(4) -#define GPU_CUR_GOVERNOR BIT(5) -#define GPU_TEMPERATURE BIT(6) - -/* MEMORY attributes */ -#define MEMORY_TOTAL BIT(0) -#define MEMORY_AVAILABLE BIT(1) -#define MEMORY_FREE BIT(2) -#define MEMORY_FAULT_AROUND_BYTES BIT(3) - -/* BATTERY attributes */ -#define BATTERY_CAPACITY BIT(0) -#define BATTERY_CHARGING_STATUS BIT(1) -#define BATTERY_TEMPERATURE BIT(2) - -#endif /* __MONITOR_INTERNAL__ */ diff --git a/include/util/resource.h b/include/util/resource.h index 21f22de..5064e43 100644 --- a/include/util/resource.h +++ b/include/util/resource.h @@ -24,6 +24,16 @@ #include #include "common.h" +enum monitor_data_type { + DATA_TYPE_UNKNOWN = 0, + DATA_TYPE_INT, + DATA_TYPE_DOUBLE, + DATA_TYPE_STRING, + DATA_TYPE_ARRAY, + + DATA_TYPE_NUM +}; + struct resource; struct resource_attribute; diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt new file mode 100644 index 0000000..8119f45 --- /dev/null +++ b/lib/CMakeLists.txt @@ -0,0 +1,49 @@ +PROJECT(libpass C) + +SET(NAME pass) +SET(VERSION_MAJOR 0) +SET(VERSION "${VERSION_MAJOR}.1.0") + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(EXEC_PREFIX "${PREFIX}/bin") +SET(INCLUDEDIR "${PREFIX}/include") +SET(LIBDIR ${CMAKE_LIBDIR_PREFIX}) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src) + +SET(PKG_MODULES + dlog + gio-2.0 + glib-2.0 +) + +INCLUDE(FindPkgConfig) +pkg_check_modules(pkgs REQUIRED ${PKG_MODULES}) + +FOREACH(flag ${pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -fPIC") +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer -finstrument-functions") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -lrt") +SET(CMAKE_EXE_LINKER_FLAGS "-pie") + +SET(SRCS ./tmonitor/tmonitor.c) + +ADD_LIBRARY( ${PROJECT_NAME} SHARED ${SRCS}) +TARGET_LINK_LIBRARIES( ${PROJECT_NAME} ${pkgs_LDFLAGS} -ldl -Wl,-z,nodelete,--no-undefined) +SET_TARGET_PROPERTIES( ${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION_MAJOR}) +SET_TARGET_PROPERTIES( ${PROJECT_NAME} PROPERTIES VERSION ${VERSION}) +SET_TARGET_PROPERTIES( ${PROJECT_NAME} PROPERTIES OUTPUT_NAME ${NAME}) + +CONFIGURE_FILE( ${CMAKE_SOURCE_DIR}/packaging/${NAME}.pc.in + ${CMAKE_SOURCE_DIR}/packaging/${NAME}.pc + @ONLY) +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIBDIR}) +INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tmonitor/ + DESTINATION ${INCLUDEDIR}/${NAME}/ + FILES_MATCHING PATTERN "*.h") +INSTALL(FILES ${CMAKE_SOURCE_DIR}/packaging/${NAME}.pc + DESTINATION ${LIBDIR}/pkgconfig) diff --git a/lib/tmonitor/tmonitor.c b/lib/tmonitor/tmonitor.c new file mode 100644 index 0000000..5b0071d --- /dev/null +++ b/lib/tmonitor/tmonitor.c @@ -0,0 +1,90 @@ +/* + * PASS (Power Aware System Service) - Tizen Monitor Library + * + * Copyright (c) 2022 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 + +#define _GNU_SOURCE +#include + +extern char *program_invocation_name; + +#ifndef EXPORT +#define EXPORT __attribute__ ((visibility("default"))) +#endif + +EXPORT +int tmonitor_init(int period, int (*func)(void *data, void* user_data), void *user_data) +{ + /* TODO */ + return 0; +} + +EXPORT +void tmonitor_exit(int id) +{ + /* TODO */ +} + +EXPORT +int tmonitor_set_attrs(int id, int resource_type, u_int64_t attr_mask) +{ + /* TODO */ + return 0; +} + +EXPORT +int tmonitor_get_available_attrs(int id, int resource_type, + int *available_attrs[], int *num_attrs) +{ + /* TODO */ + return 0; +} + +EXPORT +int tmonitor_start(int id) +{ + /* TODO */ + return 0; +} + +EXPORT +void tmonitor_stop(int id) +{ + /* TODO */ +} + +EXPORT +int tmonitor_update(int id) +{ + /* TODO */ + return 0; +} + +EXPORT +int tmonitor_get_value_int(int id, int resource_type, u_int64_t attr) +{ + /* TODO */ + return 0; +} + +EXPORT +int tmonitor_get_resource_num(int id, int resource_type) +{ + /* TODO */ + return 0; +} diff --git a/lib/tmonitor/tmonitor.h b/lib/tmonitor/tmonitor.h new file mode 100644 index 0000000..344ae45 --- /dev/null +++ b/lib/tmonitor/tmonitor.h @@ -0,0 +1,151 @@ +/* + * PASS (Power Aware System Service) - Tizen Monitor Header File + * + * Copyright (c) 2022 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 __TMONITOR__ +#define __TMONITOR__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define BIT(x) (1ULL << x) + +/** + * @brief Define the supported resource type for monitoring + */ +#define RESOURCE_TYPE_UNKNOWN 0 +#define RESOURCE_TYPE_CPU 1 +#define RESOURCE_TYPE_BUS 2 +#define RESOURCE_TYPE_GPU 3 +#define RESOURCE_TYPE_MEMORY 4 +#define RESOURCE_TYPE_BATTERY 5 +#define RESOURCE_TYPE_PROCESS 6 +#define RESOURCE_TYPE_NONSTANDARD 99 + +/** + * @brief Define the supported attributes according to resource type + */ +#define CPU_CUR_FREQ BIT(0) +#define CPU_MIN_FREQ BIT(1) +#define CPU_MAX_FREQ BIT(2) +#define CPU_AVAILABLE_MIN_FREQ BIT(3) +#define CPU_AVAILABLE_MAX_FREQ BIT(4) +#define CPU_CUR_GOVERNOR BIT(5) +#define CPU_ONLINE_CPU BIT(6) +#define CPU_TEMPERATURE BIT(7) + +#define BUS_CUR_FREQ BIT(0) +#define BUS_MIN_FREQ BIT(1) +#define BUS_MAX_FREQ BIT(2) +#define BUS_AVAILABLE_MIN_FREQ BIT(3) +#define BUS_AVAILABLE_MAX_FREQ BIT(4) +#define BUS_CUR_GOVERNOR BIT(5) + +#define GPU_CUR_FREQ BIT(0) +#define GPU_MIN_FREQ BIT(1) +#define GPU_MAX_FREQ BIT(2) +#define GPU_AVAILABLE_MIN_FREQ BIT(3) +#define GPU_AVAILABLE_MAX_FREQ BIT(4) +#define GPU_CUR_GOVERNOR BIT(5) +#define GPU_TEMPERATURE BIT(6) + +#define MEMORY_TOTAL BIT(0) +#define MEMORY_AVAILABLE BIT(1) +#define MEMORY_FREE BIT(2) +#define MEMORY_FAULT_AROUND_BYTES BIT(3) + +#define BATTERY_CAPACITY BIT(0) +#define BATTERY_CHARGING_STATUS BIT(1) +#define BATTERY_TEMPERATURE BIT(2) + +/** + * @brief Initialize the tizen monitor + * @param[in] Timer period (unit: millisecond, minimum value is 100ms) + * @param[in] Timer callback function + * @param[in] User data be passed to timer callback function + * @return @c positive integer on success, otherwise a negative error value + */ +int tmonitor_init(int period, int (*func)(void *data, void* user_data), void *user_data); + +/** + * @brief Exit the tizem monitor + * @param[in] Unique id of tizen monitor which be returnted by tmonitor_init + */ +void tmonitor_exit(int id); + +/** + * @brief Set the interested attributes for monitoring + * @param[in] Unique id of tizen monitor + * @param[in] Resource type + * @param[in] Attribute mask including the various attributes + * @return @c 0 on success, otherwise a negative error value + */ +int tmonitor_set_attrs(int id, int resource_type, u_int64_t attr_mask); + +/** + * @brief Get the available attribute list according to resource type + * @param[in] Unique id of tizen monitor + * @param[in] Resource type + * @param[out] List of available attribute list + * @param[out] Number of available attributes + * @return @c 0 on success, otherwise a negative error value + */ +int tmonitor_get_available_attrs(int id, int resource_type, + int *available_attrs[], int *num_attrs); + +/** + * @brief Start tizen monitor with asynchronous method + * @param[in] Unique id of tizen monitor + * @return @c 0 on success, otherwise a negative error value + */ +int tmonitor_start(int id); + +/** + * @brief Stop tizen monitor + * @param[in] Unique id of tizen monitor + */ +void tmonitor_stop(int id); + +/** + * @brief Update value of the interested attributes by tmonitor_set_attrs() + * @param[in] Unique id of tizen monitor + * @return @c 0 on success, otherwise a negative error value + */ +int tmonitor_update(int id); + +/** + * @brief Get integer value of resource attribute + * @param[in] Unique id of tizen monitor + * @param[in] Resource type + * @param[in] Resoruce attribute id + * @return @c positive integer value, otherwise a negative error value + */ +int tmonitor_get_value_int(int id, int resource_type, u_int64_t attr); + +/** + * @brief Get the supported resource number + * @param[in] Unique id of tizen monitor + * @param[in] Resource type + * @return @c positive integer value, otherwise a negative error value + */ +int tmonitor_get_resource_num(int id, int resource_type); + +#ifdef __cplusplus +} +#endif +#endif /* __TMONITOR__ */ diff --git a/packaging/pass.spec b/packaging/pass.spec index 3856fc3..f21d2b0 100644 --- a/packaging/pass.spec +++ b/packaging/pass.spec @@ -3,6 +3,7 @@ %define daemon_name pass %define haltest_name pass-haltests %define unittest_name pass-unittest +%define libpass_name libpass Name: %{daemon_name} Summary: Power Aware System Service @@ -51,6 +52,22 @@ Requires: pass = %{version}-%{release} %description -n %{unittest_name} PASS unit test package with gtest +%package -n %{libpass_name} +Summary: Tizen Monitor Library package +Group: Development/Libraries +Requires: pass = %{version}-%{release} + +%description -n %{libpass_name} +Tizen Monitor Library package + +%package -n %{libpass_name}-devel +Summary: Tizen Monitor Headler Files +Group: Development/Libraries +Requires: pass = %{version}-%{release} + +%description -n %{libpass_name}-devel +Tizen Monitor Headler Files + %prep %setup -q @@ -105,3 +122,14 @@ systemctl daemon-reload %files -n %{unittest_name} %defattr(-,root,root,-) %{_bindir}/pass-unittests + +%files -n %{libpass_name} +%license LICENSE +%manifest %{name}.manifest +%defattr(-,root,root,-) +%{_libdir}/*.so* + +%files -n %{libpass_name}-devel +%defattr(-,root,root,-) +%{_includedir}/%{name}/*.h +%{_libdir}/pkgconfig/%{name}.pc diff --git a/src/resource/resource-bus.c b/src/resource/resource-bus.c index a97d6f5..51e6f79 100644 --- a/src/resource/resource-bus.c +++ b/src/resource/resource-bus.c @@ -30,7 +30,7 @@ #include #include -#include +#include static int bus_get_cur_freq(const struct resource *res, const struct resource_attribute *attr, @@ -176,7 +176,7 @@ static const struct resource_attribute bus_attrs[] = { static const struct resource_driver bus_resource_driver = { .name = "Memory Bus", - .type = PASS_RESOURCE_BUS_ID, + .type = RESOURCE_TYPE_BUS, .attrs = bus_attrs, .num_attrs = ARRAY_SIZE(bus_attrs), }; diff --git a/src/resource/resource-cpu.c b/src/resource/resource-cpu.c index 7453f31..3cefa95 100644 --- a/src/resource/resource-cpu.c +++ b/src/resource/resource-cpu.c @@ -30,7 +30,7 @@ #include #include -#include +#include static int cpu_get_cur_freq(const struct resource *res, const struct resource_attribute *attr, @@ -204,7 +204,7 @@ static const struct resource_attribute cpu_attrs[] = { static const struct resource_driver cpu_resource_driver = { .name = "CPU", - .type = PASS_RESOURCE_CPU_ID, + .type = RESOURCE_TYPE_CPU, .attrs = cpu_attrs, .num_attrs = ARRAY_SIZE(cpu_attrs), }; diff --git a/src/resource/resource-gpu.c b/src/resource/resource-gpu.c index 02141f5..1bf885c 100644 --- a/src/resource/resource-gpu.c +++ b/src/resource/resource-gpu.c @@ -30,7 +30,7 @@ #include #include -#include +#include static int gpu_get_cur_freq(const struct resource *res, const struct resource_attribute *attr, @@ -190,7 +190,7 @@ static const struct resource_attribute gpu_attrs[] = { static const struct resource_driver gpu_resource_driver = { .name = "GPU", - .type = PASS_RESOURCE_GPU_ID, + .type = RESOURCE_TYPE_GPU, .attrs = gpu_attrs, .num_attrs = ARRAY_SIZE(gpu_attrs), }; diff --git a/src/resource/resource-memory.c b/src/resource/resource-memory.c index d0b24c7..c571329 100644 --- a/src/resource/resource-memory.c +++ b/src/resource/resource-memory.c @@ -30,7 +30,7 @@ #include #include -#include +#include #define PROC_MEM_INFO_PATH "/proc/meminfo" #define PROC_MEM_INFO_MEM_TOTAL "MemTotal" @@ -147,7 +147,7 @@ static const struct resource_attribute memory_attrs[] = { static const struct resource_driver cpu_resource_driver = { .name = "MEMORY", - .type = PASS_RESOURCE_MEMORY_ID, + .type = RESOURCE_TYPE_MEMORY, .attrs = memory_attrs, .num_attrs = ARRAY_SIZE(memory_attrs), }; diff --git a/src/util/resource.c b/src/util/resource.c index fad00aa..523a0dc 100644 --- a/src/util/resource.c +++ b/src/util/resource.c @@ -23,7 +23,8 @@ #include #include -#include +#define RESOURCE_ATTR_MASK (ULLONG_MAX) +#define RESOURCE_ATTR_INDEX(id) (63 - __builtin_clzll(id)) static GList *g_resource_driver_head; -- 2.7.4 From 8cdef20ec828a62b9ecb9b4d5a7ec2449391372c Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Sun, 6 Feb 2022 17:18:27 +0900 Subject: [PATCH 04/16] pass: rescon: Move overriable property into pass_rescon struct The 'overriable' property is used for only rescon module. It means that be able to move 'overriable' property from struct pass_resource to struct pass_rescon for more capsulation. Change-Id: Icd63b1b25fb8dcb64fd1d9fd894d2b604f10ea22 Signed-off-by: Chanwoo Choi --- src/pass/pass-parser.c | 3 +-- src/pass/pass-rescon.c | 8 ++++---- src/pass/pass.h | 6 +++--- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/pass/pass-parser.c b/src/pass/pass-parser.c index 51ab817..e56821c 100644 --- a/src/pass/pass-parser.c +++ b/src/pass/pass-parser.c @@ -874,8 +874,6 @@ static int parse_resource(struct pass *pass, json_object *obj) cur->init_data.memory.fault_around_bytes = -1; - cur->overridable = 1; - ret = parse_resource_data(pass, i, resource_obj); if (ret < 0) { _E("cannot parse of %dth resource in 'device_list' section\n", i); @@ -965,6 +963,7 @@ int pass_parser_get_each_resource_config(struct pass_resource *res, char *path) res->rescon.min_level = INIT_VALUE; res->rescon.max_level = INIT_VALUE; res->rescon.init_scenario_level = INIT_VALUE; + res->rescon.overridable = 1; /* Initialize the CPUHP's data */ cpuhp->pass_cpu_threshold = 0; diff --git a/src/pass/pass-rescon.c b/src/pass/pass-rescon.c index c06c00d..35735d0 100644 --- a/src/pass/pass-rescon.c +++ b/src/pass/pass-rescon.c @@ -149,7 +149,7 @@ static int rescon_update(struct pass_resource *res) int ret, i; int failed = 0; - if (!res->overridable) + if (!rescon->overridable) return 0; /* @@ -349,7 +349,7 @@ static void rescon_set_scenario_level(struct pass_resource *res, { struct pass_rescon *rescon = &res->rescon; - if (scenario_level < 0 || !res->overridable) + if (scenario_level < 0 || !rescon->overridable) return; g_mutex_lock(&rescon->scenario_level_mutex); @@ -364,7 +364,7 @@ static void rescon_unset_scenario_level(struct pass_resource *res, { struct pass_rescon *rescon = &res->rescon; - if (scenario_level < 0 || !res->overridable) + if (scenario_level < 0 || !rescon->overridable) return; g_mutex_lock(&rescon->scenario_level_mutex); @@ -524,7 +524,7 @@ int pass_rescon_set_overridable(struct pass_resource *res, int overridable) if (!res) return -EINVAL; - res->overridable = overridable; + res->rescon.overridable = overridable; return 0; } diff --git a/src/pass/pass.h b/src/pass/pass.h index 0b43ad6..dfb4c86 100644 --- a/src/pass/pass.h +++ b/src/pass/pass.h @@ -287,6 +287,9 @@ struct pass_rescon { /** State of PASS_MODULE_RESCON */ enum pass_state state; + /** Representing whether this resource can be overridden or not */ + int overridable; + /** * Initial level when initializing h/w resource by resource controller. * If value is -1, it is not initialized by parser. @@ -637,9 +640,6 @@ struct pass_resource { struct pass_pmqos pmqos; /** Instance of PASS_MODULE_THERMAL module */ struct pass_thermal thermal; - - /** Representing whether this resource can be overridden or not */ - int overridable; }; /****************************************************** -- 2.7.4 From ea01c7c00d5043af02a743d0452b4f97c50ad395 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Sun, 6 Feb 2022 17:13:48 +0900 Subject: [PATCH 05/16] util: resource: Add resource_device struct and functions Add resource_device structure for expressing the each h/w resource such as CPU, GPU, Memory BUS, battery and so on. Each h/w board has the different h/w resource information such as the number of h/w resource, name, access path and so on. PASS daemon has already supported the configuration method to get the h/w resource information like /hal/etc/pass/pass.json. Each h/w resource has the unique name, resource type and resource index because board is able to have the one more same resource like big.LITTLE cpu cluster. When creating the instance of struct resource, will use the struct resource_drvier and resource_device with resource type and index argument because the user of create_resource() cannot get the unique resource name which depends on the specific h/w. But the user of create_resource() can get the available count of specific resource type by get_resource_device_*(). [How to create the instance of struct resource] 1. Find resource_device with resource type and index 2. Find resource_driver with resource type 3. Create the instance of struct resource by using resouce_device/driver info. And rename from get_resource_driver to find_resource_driver. Change-Id: I8c2fa6c8d22dcea996a12048fcab7de21eca652d Signed-off-by: Chanwoo Choi --- include/util/resource.h | 23 +++++++++++++- src/util/resource.c | 79 +++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 96 insertions(+), 6 deletions(-) diff --git a/include/util/resource.h b/include/util/resource.h index 5064e43..32745a4 100644 --- a/include/util/resource.h +++ b/include/util/resource.h @@ -78,9 +78,21 @@ struct resource_driver { const struct resource_attribute *attrs; }; +struct resource_device { + char *name; + int type; + + /* + * Never initialize it by user of add_resource_device(). + * It will be initialized by add_resource_device function automatically. + */ + int index; +}; + struct resource { char *name; int type; + int index; void *user_data; int num_attrs; @@ -98,12 +110,21 @@ static void __DESTRUCTOR__ module_exit(void) \ remove_resource_driver(resource_driver); \ } +/* Add/remove resource driver and device */ 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); +int get_resource_device_count_all(void); +int get_resource_device_count(int resource_type); +const struct resource_device *find_resource_device(int resource_type, int resource_index); +int add_resource_device(struct resource_device *resource_device); +void remove_resource_device(struct resource_device *resource_device); + +/* Create/delete resource instance */ +struct resource *create_resource(int resource_type, int resource_index, void *user_data); void delete_resource(struct resource *resource); +/* Handle resource attribute */ int update_resource_attr(struct resource *resource, u_int64_t attr_id); int update_resource_attrs(struct resource *resource); int update_resource_attrs_interest(struct resource *resource, u_int64_t attr_interest_mask); diff --git a/src/util/resource.c b/src/util/resource.c index 523a0dc..6805dec 100644 --- a/src/util/resource.c +++ b/src/util/resource.c @@ -27,6 +27,7 @@ #define RESOURCE_ATTR_INDEX(id) (63 - __builtin_clzll(id)) static GList *g_resource_driver_head; +static GList *g_resource_device_head; static gint __compare_resource_type(gconstpointer data, gconstpointer input) { @@ -56,7 +57,68 @@ void remove_resource_driver(const struct resource_driver *driver) g_list_remove(g_resource_driver_head, (gpointer)driver); } -const struct resource_driver *get_resource_driver(int resource_type) +int get_resource_device_count_all(void) +{ + return g_list_length(g_resource_device_head); +} + +int get_resource_device_count(int resource_type) +{ + GList *node; + struct resource_device *device; + int count = 0; + + for (node = g_resource_device_head; node != NULL; node = node->next) { + device = node->data; + if (device->type == resource_type) + count++; + } + + return count; +} + +const struct resource_device *find_resource_device(int resource_type, + int resource_index) +{ + GList *node; + const struct resource_device *device; + + for (node = g_resource_device_head; node != NULL; node = node->next) { + device = node->data; + if (device->type == resource_type && + device->index == resource_index) + return device; + } + + return NULL; +} + +int add_resource_device(struct resource_device *device) +{ + int count; + + if (!device) + return -EINVAL; + + count = get_resource_device_count(device->type); + device->index = count; + + g_resource_device_head = + g_list_append(g_resource_device_head, (gpointer)device); + + return 0; +} + +void remove_resource_device(struct resource_device *device) +{ + if (!device) + return; + + g_resource_device_head = + g_list_remove(g_resource_device_head, (gpointer)device); +} + +static const struct resource_driver *find_resource_driver(int resource_type) { GList *node; @@ -83,13 +145,19 @@ void delete_resource(struct resource *resource) free(resource); } -struct resource *create_resource(int resource_type, const char *resource_name, void *user_data) +struct resource *create_resource(int resource_type, int resource_index, + void *user_data) { + const struct resource_device *device = NULL; const struct resource_driver *driver = NULL; struct resource *resource = NULL; int i; - driver = get_resource_driver(resource_type); + device = find_resource_device(resource_type, resource_index); + if (!device) + return NULL; + + driver = find_resource_driver(resource_type); if (!driver) return NULL; @@ -97,8 +165,9 @@ struct resource *create_resource(int resource_type, const char *resource_name, v if (!resource) return NULL; - resource->type = resource_type; - resource->name = g_strdup(resource_name); + resource->type = device->type; + resource->name = g_strdup(device->name); + resource->index = device->index; resource->user_data = user_data; resource->num_attrs = driver->num_attrs; resource->attrs = driver->attrs; -- 2.7.4 From b0e947ab8bacc3f61421097ef07c1d8cf8ded774 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Sun, 6 Feb 2022 17:31:16 +0900 Subject: [PATCH 06/16] pass: Add resource_device for each h/w resource Change-Id: I1b124c8828f05103226d9d84558d45bb397cedba Signed-off-by: Chanwoo Choi --- src/pass/pass.c | 29 +++++++++++++++++++++++++++++ src/pass/pass.h | 4 ++++ 2 files changed, 33 insertions(+) diff --git a/src/pass/pass.c b/src/pass/pass.c index b0a56bd..ac70225 100644 --- a/src/pass/pass.c +++ b/src/pass/pass.c @@ -276,8 +276,32 @@ static int pass_init_resource(struct pass_resource *res) } } + /* Add resource_device according to h/w resource information */ + res->device = calloc(1, sizeof(*res->device)); + if (!res->device) { + ret = -ENOMEM; + goto err_res_dev; + } + + res->device->name = res->config_data.res_name; + res->device->type = res->config_data.res_type; + + ret = add_resource_device(res->device); + if (ret < 0) { + _E("cannot add resource device (res_name:%s, res_type%d)", + res->config_data.res_name, + res->config_data.res_type); + goto err; + } + return 0; +err: + free(res->device); +err_res_dev: + if (is_supported_module(res, PASS_MODULE_THERMAL)) + if (pass_thermal_exit(res) < 0) + _E("cannot exit PASS Thermal"); err_thermal: if (is_supported_module(res, PASS_MODULE_PMQOS)) if (pass_pmqos_exit(res) < 0) @@ -308,6 +332,11 @@ static int pass_exit_resource(struct pass_resource *res) { int ret; + /* Remove resource_device */ + remove_resource_device(res->device); + free(res->device); + res->device = NULL; + /* Put configuration of each resource from pass-resource*.conf */ pass_parser_put_each_resource_config(res); diff --git a/src/pass/pass.h b/src/pass/pass.h index dfb4c86..89b31d3 100644 --- a/src/pass/pass.h +++ b/src/pass/pass.h @@ -38,6 +38,7 @@ #include #include +#include #define PASS_LEVEL_COND_MAX 3 @@ -640,6 +641,9 @@ struct pass_resource { struct pass_pmqos pmqos; /** Instance of PASS_MODULE_THERMAL module */ struct pass_thermal thermal; + + /** Instance of resouce device containing h/w resource information */ + struct resource_device *device; }; /****************************************************** -- 2.7.4 From 14bc089beb54c2c2d3817762486e08520e1226e0 Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Fri, 4 Feb 2022 13:16:20 +0900 Subject: [PATCH 07/16] util: resource: Use internal interest_mask Since interesting attributes might not be changed usually, it seems better that each resource has interest_mask internally. Change-Id: I6276dbb688ee4a3c5f68eff323bce6c5b1e967a1 Signed-off-by: Dongwoo Lee --- include/util/resource.h | 6 +++--- src/util/resource.c | 22 +++++++++++++++------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/include/util/resource.h b/include/util/resource.h index 32745a4..64d6e2f 100644 --- a/include/util/resource.h +++ b/include/util/resource.h @@ -98,6 +98,7 @@ struct resource { int num_attrs; const struct resource_attribute *attrs; struct resource_attribute_value *attrs_value; + u_int64_t attr_interest; }; #define RESOURCE_DRIVER_REGISTER(resource_driver) \ @@ -127,12 +128,11 @@ void delete_resource(struct resource *resource); /* Handle resource attribute */ int update_resource_attr(struct resource *resource, u_int64_t attr_id); int update_resource_attrs(struct resource *resource); -int update_resource_attrs_interest(struct resource *resource, u_int64_t attr_interest_mask); - const struct resource_attribute *get_resource_attr(struct resource *resource, u_int64_t attr_id); struct resource_attribute_value * get_resource_attr_value(struct resource *resource, u_int64_t attr_id); int get_resource_attr_integer(struct resource *resource, u_int64_t attr_id); int get_resource_attr_integer_sync(struct resource *resource, u_int64_t attr_id); - +void set_resource_attr_interest(struct resource *resource, u_int64_t interest_mask); +void unset_resource_attr_interest(struct resource *resource, u_int64_t interest_mask); #endif diff --git a/src/util/resource.c b/src/util/resource.c index 6805dec..ff766ee 100644 --- a/src/util/resource.c +++ b/src/util/resource.c @@ -213,7 +213,7 @@ int update_resource_attr(struct resource *resource, u_int64_t attr_id) return 0; } -int update_resource_attrs_interest(struct resource *resource, u_int64_t interest_mask) +int update_resource_attrs(struct resource *resource) { int i, ret; @@ -221,7 +221,7 @@ int update_resource_attrs_interest(struct resource *resource, u_int64_t interest return -EINVAL; for (i = 0; i < resource->num_attrs; i++) { - if (!(resource->attrs[i].id & interest_mask)) + if (!(resource->attrs[i].id & resource->attr_interest)) continue; ret = update_resource_attr(resource, resource->attrs[i].id); if (ret < 0) { @@ -232,11 +232,6 @@ int update_resource_attrs_interest(struct resource *resource, u_int64_t interest return 0; } -int update_resource_attrs(struct resource *resource) -{ - return update_resource_attrs_interest(resource, RESOURCE_ATTR_MASK); -} - const struct resource_attribute * get_resource_attr(struct resource *resource, u_int64_t attr_id) { @@ -269,6 +264,9 @@ int get_resource_attr_integer(struct resource *resource, u_int64_t attr_id) if (!attr || attr->type != DATA_TYPE_INT) return -EINVAL; + if (!(attr->id & resource->attr_interest)) + return -EINVAL; + attr_value = get_resource_attr_value(resource, attr_id); if (!attr_value) return -EINVAL; @@ -286,3 +284,13 @@ int get_resource_attr_integer_sync(struct resource *resource, u_int64_t attr_id) return get_resource_attr_integer(resource, attr_id); } + +void set_resource_attr_interest(struct resource *resource, u_int64_t interest_mask) +{ + resource->attr_interest |= interest_mask; +} + +void unset_resource_attr_interest(struct resource *resource, u_int64_t interest_mask) +{ + resource->attr_interest &= ~interest_mask; +} -- 2.7.4 From 2cab161a2696afcb1e63c25f987bb90168e9207f Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Fri, 4 Feb 2022 16:24:35 +0900 Subject: [PATCH 08/16] resource: Rework attribute value handling Change-Id: I8777093c47963a84913b9f7388816cd8cd455d58 Signed-off-by: Dongwoo Lee --- include/util/resource.h | 39 ++++++----- src/resource/resource-bus.c | 49 ++++++++----- src/resource/resource-cpu.c | 53 +++++++++------ src/resource/resource-gpu.c | 51 +++++++++----- src/resource/resource-memory.c | 24 ++++--- src/util/resource.c | 151 ++++++++++++++++++++++++++++++++++++----- 6 files changed, 270 insertions(+), 97 deletions(-) diff --git a/include/util/resource.h b/include/util/resource.h index 64d6e2f..657a921 100644 --- a/include/util/resource.h +++ b/include/util/resource.h @@ -37,31 +37,24 @@ enum monitor_data_type { struct resource; struct resource_attribute; -struct resource_attribute_value { - /* Indicate the data type among three types (int/double/str)*/ +struct array_value { int type; + int length; + void *data; +}; - 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_value { + int type; + void *data; }; struct resource_attribute_ops { int (*set)(const struct resource *res, const struct resource_attribute *attr, - const char *buf, int count, void *user_data); + const void *data, int count, void *user_data); int (*get)(const struct resource *res, const struct resource_attribute *attr, - char *buf, void *user_data); + void **data, void *user_data); }; struct resource_attribute { @@ -131,8 +124,18 @@ int update_resource_attrs(struct resource *resource); const struct resource_attribute *get_resource_attr(struct resource *resource, u_int64_t attr_id); struct resource_attribute_value * get_resource_attr_value(struct resource *resource, u_int64_t attr_id); -int get_resource_attr_integer(struct resource *resource, u_int64_t attr_id); -int get_resource_attr_integer_sync(struct resource *resource, u_int64_t attr_id); + +int get_resource_attr_integer(struct resource *resource, u_int64_t attr_id, int *data); +int get_resource_attr_integer_sync(struct resource *resource, u_int64_t attr_id, int *data); +int get_resource_attr_double(struct resource *resource, u_int64_t attr_id, double *data); +int get_resource_attr_double_sync(struct resource *resource, u_int64_t attr_id, double *data); +int get_resource_attr_string(struct resource *resource, u_int64_t attr_id, char **data); +int get_resource_attr_string_sync(struct resource *resource, u_int64_t attr_id, char **data); +int get_resource_attr_array(struct resource *resource, u_int64_t attr_id, + struct array_value **data); +int get_resource_attr_array_sync(struct resource *resource, u_int64_t attr_id, + struct array_value **data); + void set_resource_attr_interest(struct resource *resource, u_int64_t interest_mask); void unset_resource_attr_interest(struct resource *resource, u_int64_t interest_mask); #endif diff --git a/src/resource/resource-bus.c b/src/resource/resource-bus.c index 51e6f79..826f209 100644 --- a/src/resource/resource-bus.c +++ b/src/resource/resource-bus.c @@ -34,97 +34,112 @@ static int bus_get_cur_freq(const struct resource *res, const struct resource_attribute *attr, - char *buf, void *user_data) + void **data, void *user_data) { int val; - if (!res || !attr || !buf) + if (!res || !attr || !data) return -EINVAL; val = hal_power_dvfs_get_curr_freq(res->type, res->name); if (val < 0) return -EINVAL; - return sprintf(buf, "%d", val); + *data = (void *)(intptr_t)val; + + return 0; } static int bus_get_min_freq(const struct resource *res, const struct resource_attribute *attr, - char *buf, void *user_data) + void **data, void *user_data) { int val; - if (!res || !attr || !buf) + if (!res || !attr || !data) return -EINVAL; val = hal_power_dvfs_get_min_freq(res->type, res->name); if (val < 0) return -EINVAL; - return sprintf(buf, "%d", val); + *data = (void *)(intptr_t)val; + + return 0; } static int bus_get_max_freq(const struct resource *res, const struct resource_attribute *attr, - char *buf, void *user_data) + void **data, void *user_data) { int val; - if (!res || !attr || !buf) + if (!res || !attr || !data) return -EINVAL; val = hal_power_dvfs_get_max_freq(res->type, res->name); if (val < 0) return -EINVAL; - return sprintf(buf, "%d", val); + *data = (void *)(intptr_t)val; + + return 0; } static int bus_get_available_min_freq(const struct resource *res, const struct resource_attribute *attr, - char *buf, void *user_data) + void **data, void *user_data) { int val; - if (!res || !attr || !buf) + if (!res || !attr || !data) return -EINVAL; val = hal_power_dvfs_get_available_min_freq(res->type, res->name); if (val < 0) return -EINVAL; - return sprintf(buf, "%d", val); + *data = (void *)(intptr_t)val; + + return 0; } static int bus_get_available_max_freq(const struct resource *res, const struct resource_attribute *attr, - char *buf, void *user_data) + void **data, void *user_data) { int val; - if (!res || !attr || !buf) + if (!res || !attr || !data) return -EINVAL; val = hal_power_dvfs_get_available_max_freq(res->type, res->name); if (val < 0) return -EINVAL; - return sprintf(buf, "%d", val); + *data = (void *)(intptr_t)val; + + return 0; } static int bus_get_curr_governor(const struct resource *res, const struct resource_attribute *attr, - char *buf, void *user_data) + void **data, void *user_data) { + char buf[BUFF_MAX]; int val; - if (!res || !attr || !buf) + if (!res || !attr || !data) return -EINVAL; val = hal_power_dvfs_get_curr_governor(res->type, res->name, buf); if (val < 0) return -EINVAL; + *data = strdup(buf); + if (!*data) + return -ENOMEM; + return 0; } diff --git a/src/resource/resource-cpu.c b/src/resource/resource-cpu.c index 3cefa95..de30d38 100644 --- a/src/resource/resource-cpu.c +++ b/src/resource/resource-cpu.c @@ -34,110 +34,125 @@ static int cpu_get_cur_freq(const struct resource *res, const struct resource_attribute *attr, - char *buf, void *user_data) + void **data, void *user_data) { int val; - if (!res || !attr || !buf) + if (!res || !attr || !data) return -EINVAL; val = hal_power_dvfs_get_curr_freq(res->type, res->name); if (val < 0) return -EINVAL; - return sprintf(buf, "%d", val); + *data = (void *)(intptr_t)val; + + return 0; } static int cpu_get_min_freq(const struct resource *res, const struct resource_attribute *attr, - char *buf, void *user_data) + void **data, void *user_data) { int val; - if (!res || !attr || !buf) + if (!res || !attr || !data) return -EINVAL; val = hal_power_dvfs_get_min_freq(res->type, res->name); if (val < 0) return -EINVAL; - return sprintf(buf, "%d", val); + *data = (void *)(intptr_t)val; + + return 0; } static int cpu_get_max_freq(const struct resource *res, const struct resource_attribute *attr, - char *buf, void *user_data) + void **data, void *user_data) { int val; - if (!res || !attr || !buf) + if (!res || !attr || !data) return -EINVAL; val = hal_power_dvfs_get_max_freq(res->type, res->name); if (val < 0) return -EINVAL; - return sprintf(buf, "%d", val); + *data = (void *)(intptr_t)val; + + return 0; } static int cpu_get_available_min_freq(const struct resource *res, const struct resource_attribute *attr, - char *buf, void *user_data) + void **data, void *user_data) { int val; - if (!res || !attr || !buf) + if (!res || !attr || !data) return -EINVAL; val = hal_power_dvfs_get_available_min_freq(res->type, res->name); if (val < 0) return -EINVAL; - return sprintf(buf, "%d", val); + *data = (void *)(intptr_t)val; + + return 0; } static int cpu_get_available_max_freq(const struct resource *res, const struct resource_attribute *attr, - char *buf, void *user_data) + void **data, void *user_data) { int val; - if (!res || !attr || !buf) + if (!res || !attr || !data) return -EINVAL; val = hal_power_dvfs_get_available_max_freq(res->type, res->name); if (val < 0) return -EINVAL; - return sprintf(buf, "%d", val); + *data = (void *)(intptr_t)val; + + return 0; } static int cpu_get_curr_governor(const struct resource *res, const struct resource_attribute *attr, - char *buf, void *user_data) + void **data, void *user_data) { + char buf[BUFF_MAX]; int val; - if (!res || !attr || !buf) + if (!res || !attr || !data) return -EINVAL; val = hal_power_dvfs_get_curr_governor(res->type, res->name, buf); if (val < 0) return -EINVAL; + *data = strdup(buf); + if (!*data) + return -ENOMEM; + return 0; } static int cpu_get_online_cpu(const struct resource *res, const struct resource_attribute *attr, - char *buf, void *user_data) + void **data, void *user_data) { return 0; } static int cpu_get_temperature(const struct resource *res, const struct resource_attribute *attr, - char *buf, void *user_data) + void **data, void *user_data) { return 0; } diff --git a/src/resource/resource-gpu.c b/src/resource/resource-gpu.c index 1bf885c..87acc82 100644 --- a/src/resource/resource-gpu.c +++ b/src/resource/resource-gpu.c @@ -34,103 +34,118 @@ static int gpu_get_cur_freq(const struct resource *res, const struct resource_attribute *attr, - char *buf, void *user_data) + void **data, void *user_data) { int val; - if (!res || !attr || !buf) + if (!res || !attr || !data) return -EINVAL; val = hal_power_dvfs_get_curr_freq(res->type, res->name); if (val < 0) return -EINVAL; - return sprintf(buf, "%d", val); + *data = (void *)(intptr_t)val; + + return 0; } static int gpu_get_min_freq(const struct resource *res, const struct resource_attribute *attr, - char *buf, void *user_data) + void **data, void *user_data) { int val; - if (!res || !attr || !buf) + if (!res || !attr || !data) return -EINVAL; val = hal_power_dvfs_get_min_freq(res->type, res->name); if (val < 0) return -EINVAL; - return sprintf(buf, "%d", val); + *data = (void *)(intptr_t)val; + + return 0; } static int gpu_get_max_freq(const struct resource *res, const struct resource_attribute *attr, - char *buf, void *user_data) + void **data, void *user_data) { int val; - if (!res || !attr || !buf) + if (!res || !attr || !data) return -EINVAL; val = hal_power_dvfs_get_max_freq(res->type, res->name); if (val < 0) return -EINVAL; - return sprintf(buf, "%d", val); + *data = (void *)(intptr_t)val; + + return 0; } static int gpu_get_available_min_freq(const struct resource *res, const struct resource_attribute *attr, - char *buf, void *user_data) + void **data, void *user_data) { int val; - if (!res || !attr || !buf) + if (!res || !attr || !data) return -EINVAL; val = hal_power_dvfs_get_available_min_freq(res->type, res->name); if (val < 0) return -EINVAL; - return sprintf(buf, "%d", val); + *data = (void *)(intptr_t)val; + + return 0; } static int gpu_get_available_max_freq(const struct resource *res, const struct resource_attribute *attr, - char *buf, void *user_data) + void **data, void *user_data) { int val; - if (!res || !attr || !buf) + if (!res || !attr || !data) return -EINVAL; val = hal_power_dvfs_get_available_max_freq(res->type, res->name); if (val < 0) return -EINVAL; - return sprintf(buf, "%d", val); + *data = (void *)(intptr_t)val; + + return 0; } static int gpu_get_curr_governor(const struct resource *res, const struct resource_attribute *attr, - char *buf, void *user_data) + void **data, void *user_data) { + char buf[BUFF_MAX]; int val; - if (!res || !attr || !buf) + if (!res || !attr || !data) return -EINVAL; val = hal_power_dvfs_get_curr_governor(res->type, res->name, buf); if (val < 0) return -EINVAL; + *data = strdup(buf); + if (!*data) + return -ENOMEM; + return 0; } static int gpu_get_temperature(const struct resource *res, const struct resource_attribute *attr, - char *buf, void *user_data) + void **data, void *user_data) { return 0; } diff --git a/src/resource/resource-memory.c b/src/resource/resource-memory.c index c571329..5d5742f 100644 --- a/src/resource/resource-memory.c +++ b/src/resource/resource-memory.c @@ -74,50 +74,56 @@ static inline int memory_read_val_from_proc_node(uint32_t val_id) static int memory_get_total_memory(const struct resource *res, const struct resource_attribute *attr, - char *buf, void *user_data) + void **data, void *user_data) { int val; - if (!res || !attr || !buf) + if (!res || !attr || !data) return -EINVAL; val = memory_read_val_from_proc_node(attr->id); if (val < 0) return -EINVAL; - return sprintf(buf, "%d", val); + *data = (void *)(intptr_t)val; + + return 0; } static int memory_get_available_memory(const struct resource *res, const struct resource_attribute *attr, - char *buf, void *user_data) + void **data, void *user_data) { int val; - if (!res || !attr || !buf) + if (!res || !attr || !data) return -EINVAL; val = memory_read_val_from_proc_node(attr->id); if (val < 0) return -EINVAL; - return sprintf(buf, "%d", val); + *data = (void *)(intptr_t)val; + + return 0; } static int memory_get_free_memory(const struct resource *res, const struct resource_attribute *attr, - char *buf, void *user_data) + void **data, void *user_data) { int val; - if (!res || !attr || !buf) + if (!res || !attr || !data) return -EINVAL; val = memory_read_val_from_proc_node(attr->id); if (val < 0) return -EINVAL; - return sprintf(buf, "%d", val); + *data = (void *)(intptr_t)val; + + return 0; } static const struct resource_attribute memory_attrs[] = { diff --git a/src/util/resource.c b/src/util/resource.c index ff766ee..c78b2a3 100644 --- a/src/util/resource.c +++ b/src/util/resource.c @@ -189,7 +189,6 @@ int update_resource_attr(struct resource *resource, u_int64_t 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 || attr_index < 0 || attr_index >= resource->num_attrs) @@ -201,15 +200,10 @@ int update_resource_attr(struct resource *resource, u_int64_t attr_id) if (!attr->ops.get) return -EINVAL; - ret = attr->ops.get(resource, attr, buf, resource->user_data); + ret = attr->ops.get(resource, attr, &(attr_value->data), 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; } @@ -254,27 +248,152 @@ get_resource_attr_value(struct resource *resource, u_int64_t attr_id) return &resource->attrs_value[attr_index]; } -int get_resource_attr_integer(struct resource *resource, u_int64_t attr_id) +static bool check_attr_validate(struct resource *resource, u_int64_t attr_id, int type) +{ + const struct resource_attribute *attr = get_resource_attr(resource, attr_id); + + if (!attr || attr->type != type) + return false; + + if (!(attr->id & resource->attr_interest)) + return false; + + return true; +} + +int get_resource_attr_integer(struct resource *resource, u_int64_t attr_id, int *data) { - const struct resource_attribute *attr = NULL; struct resource_attribute_value *attr_value = NULL; - /* Check whether the data type is integer or not */ - attr = get_resource_attr(resource, attr_id); - if (!attr || attr->type != DATA_TYPE_INT) + if (!check_attr_validate(resource, attr_id, DATA_TYPE_INT)) return -EINVAL; - if (!(attr->id & resource->attr_interest)) + attr_value = get_resource_attr_value(resource, attr_id); + if (!attr_value) + return -EINVAL; + + *data = (int)(intptr_t)attr_value->data; + + return 0; +} + +int get_resource_attr_integer_sync(struct resource *resource, u_int64_t attr_id, int *data) +{ + int ret; + + ret = update_resource_attr(resource, attr_id); + if (ret < 0) + return ret; + + return get_resource_attr_integer(resource, attr_id, data); +} + +int get_resource_attr_double(struct resource *resource, u_int64_t attr_id, double *data) +{ + struct resource_attribute_value *attr_value = NULL; + + if (!check_attr_validate(resource, attr_id, DATA_TYPE_DOUBLE)) return -EINVAL; attr_value = get_resource_attr_value(resource, attr_id); if (!attr_value) return -EINVAL; - return attr_value->data.int_value; + *data = (double)(intptr_t)attr_value->data; + + return 0; +} + +int get_resource_attr_double_sync(struct resource *resource, u_int64_t attr_id, double *data) +{ + int ret; + + ret = update_resource_attr(resource, attr_id); + if (ret < 0) + return ret; + + return get_resource_attr_double(resource, attr_id, data); +} + +int get_resource_attr_string(struct resource *resource, u_int64_t attr_id, char **data) +{ + struct resource_attribute_value *attr_value = NULL; + + if (!check_attr_validate(resource, attr_id, DATA_TYPE_STRING)) + return -EINVAL; + + attr_value = get_resource_attr_value(resource, attr_id); + if (!attr_value) + return -EINVAL; + + *data = (char *)attr_value->data; + + return 0; +} + +int put_resource_attr_string(struct resource *resource, u_int64_t attr_id) +{ + struct resource_attribute_value *attr_value = NULL; + + if (!check_attr_validate(resource, attr_id, DATA_TYPE_STRING)) + return -EINVAL; + + attr_value = get_resource_attr_value(resource, attr_id); + if (!attr_value || !attr_value->data) + return -EINVAL; + + free(attr_value->data); + attr_value->data = NULL; + + return 0; +} + +int get_resource_attr_string_sync(struct resource *resource, u_int64_t attr_id, char **data) +{ + int ret; + + ret = update_resource_attr(resource, attr_id); + if (ret < 0) + return ret; + + return get_resource_attr_string(resource, attr_id, data); +} + +int get_resource_attr_array(struct resource *resource, u_int64_t attr_id, struct array_value **data) +{ + struct resource_attribute_value *attr_value = NULL; + + if (!check_attr_validate(resource, attr_id, DATA_TYPE_ARRAY)) + return -EINVAL; + + attr_value = get_resource_attr_value(resource, attr_id); + if (!attr_value) + return -EINVAL; + + *data = (struct array_value *)attr_value->data; + + return 0; +} + +int put_resource_attr_array(struct resource *resource, u_int64_t attr_id) +{ + struct resource_attribute_value *attr_value = NULL; + + if (!check_attr_validate(resource, attr_id, DATA_TYPE_ARRAY)) + return -EINVAL; + + attr_value = get_resource_attr_value(resource, attr_id); + if (!attr_value || !attr_value->data) + return -EINVAL; + + free(attr_value->data); + attr_value->data = NULL; + + return 0; } -int get_resource_attr_integer_sync(struct resource *resource, u_int64_t attr_id) +int get_resource_attr_array_sync(struct resource *resource, u_int64_t attr_id, + struct array_value **data) { int ret; @@ -282,7 +401,7 @@ int get_resource_attr_integer_sync(struct resource *resource, u_int64_t attr_id) if (ret < 0) return ret; - return get_resource_attr_integer(resource, attr_id); + return get_resource_attr_array(resource, attr_id, data); } void set_resource_attr_interest(struct resource *resource, u_int64_t interest_mask) -- 2.7.4 From f967a32e5420984530a45ae600362235913ac1d7 Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Mon, 7 Feb 2022 14:19:39 +0900 Subject: [PATCH 09/16] monitor: internal: Add pointer attribute data type Change-Id: Id4d711e38a036b26a8a24af3b7e92ab4177d8445 Signed-off-by: Dongwoo Lee --- include/util/resource.h | 3 +++ src/util/resource.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/include/util/resource.h b/include/util/resource.h index 657a921..c4bd599 100644 --- a/include/util/resource.h +++ b/include/util/resource.h @@ -30,6 +30,7 @@ enum monitor_data_type { DATA_TYPE_DOUBLE, DATA_TYPE_STRING, DATA_TYPE_ARRAY, + DATA_TYPE_PTR, DATA_TYPE_NUM }; @@ -131,6 +132,8 @@ int get_resource_attr_double(struct resource *resource, u_int64_t attr_id, doubl int get_resource_attr_double_sync(struct resource *resource, u_int64_t attr_id, double *data); int get_resource_attr_string(struct resource *resource, u_int64_t attr_id, char **data); int get_resource_attr_string_sync(struct resource *resource, u_int64_t attr_id, char **data); +int get_resource_attr_ptr(struct resource *resource, u_int64_t attr_id, void **data); +int get_resource_attr_ptr_sync(struct resource *resource, u_int64_t attr_id, void **data); int get_resource_attr_array(struct resource *resource, u_int64_t attr_id, struct array_value **data); int get_resource_attr_array_sync(struct resource *resource, u_int64_t attr_id, diff --git a/src/util/resource.c b/src/util/resource.c index c78b2a3..f3f927e 100644 --- a/src/util/resource.c +++ b/src/util/resource.c @@ -404,6 +404,50 @@ int get_resource_attr_array_sync(struct resource *resource, u_int64_t attr_id, return get_resource_attr_array(resource, attr_id, data); } +int get_resource_attr_ptr(struct resource *resource, u_int64_t attr_id, void **data) +{ + struct resource_attribute_value *attr_value = NULL; + + if (!check_attr_validate(resource, attr_id, DATA_TYPE_PTR)) + return -EINVAL; + + attr_value = get_resource_attr_value(resource, attr_id); + if (!attr_value) + return -EINVAL; + + *data = attr_value->data; + + return 0; +} + +int put_resource_attr_ptr(struct resource *resource, u_int64_t attr_id) +{ + struct resource_attribute_value *attr_value = NULL; + + if (!check_attr_validate(resource, attr_id, DATA_TYPE_PTR)) + return -EINVAL; + + attr_value = get_resource_attr_value(resource, attr_id); + if (!attr_value || !attr_value->data) + return -EINVAL; + + free(attr_value->data); + attr_value->data = NULL; + + return 0; +} + +int get_resource_attr_ptr_sync(struct resource *resource, u_int64_t attr_id, void **data) +{ + int ret; + + ret = update_resource_attr(resource, attr_id); + if (ret < 0) + return ret; + + return get_resource_attr_ptr(resource, attr_id, data); +} + void set_resource_attr_interest(struct resource *resource, u_int64_t interest_mask) { resource->attr_interest |= interest_mask; -- 2.7.4 From 2712f4757ef9184a0cc26c33751c8207625e8d71 Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Mon, 7 Feb 2022 14:24:56 +0900 Subject: [PATCH 10/16] monitor: Add monitor module This introduce the new pass module monitor which provides methods for accessing or controlling resources in a common way. By just creating and queuing a request, resource attributes are updated, and we can exploit it easily. And attributes also can be filtered in order not to take unnecessary attributes by set interest mask. How to request resource update: 1) create resource 2) set interest attributes for resource 3) create monitor command 4) bind resource with command 5) submit command (sync or async) 6) if async) wait for done 7) get attributes values by 'get' function as following the corresponding type 8) PTR_TYPE, STRING_TYPE, ARRAY_TYPE attributes should be call 'put' function to release memory Change-Id: I110e46b96691381629b8da619d3519c50e409693 Signed-off-by: Chanwoo Choi Signed-off-by: Dongwoo Lee --- CMakeLists.txt | 3 ++ include/monitor/monitor.h | 55 ++++++++++++++++++++++ src/monitor/monitor-command.c | 104 ++++++++++++++++++++++++++++++++++++++++++ src/monitor/monitor-thread.c | 99 ++++++++++++++++++++++++++++++++++++++++ src/monitor/monitor.c | 84 ++++++++++++++++++++++++++++++++++ 5 files changed, 345 insertions(+) create mode 100644 include/monitor/monitor.h create mode 100644 src/monitor/monitor-command.c create mode 100644 src/monitor/monitor-thread.c create mode 100644 src/monitor/monitor.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 568afd4..6b0d426 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,9 @@ SET(SRCS src/resource/resource-bus.c src/resource/resource-gpu.c src/resource/resource-memory.c + src/monitor/monitor.c + src/monitor/monitor-thread.c + src/monitor/monitor-command.c ) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h new file mode 100644 index 0000000..08e9e21 --- /dev/null +++ b/include/monitor/monitor.h @@ -0,0 +1,55 @@ +/* + * PASS (Power Aware System Service) + * + * Copyright (c) 2022 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 __MONITOR_H__ +#define __MONITOR_H__ + +#include +#include +#include + +#define MONITOR_POLLING_DURATION 100 + +struct monitor_command { + struct resource *resource; + volatile bool done; + mtx_t lock; + cnd_t signal; +}; + +struct monitor { + struct thread *thread; + struct queue *q; + void *priv; + mtx_t lock; + cnd_t signal; +}; + +struct monitor *monitor_get(void); +int monitor_thread_init(struct monitor *monitor); +void monitor_thread_exit(struct monitor *monitor); + +void monitor_command_wait_done(struct monitor_command *cmd); +void monitor_command_submit(struct monitor_command *cmd); +void monitor_command_submit_sync(struct monitor_command *cmd); +void monitor_command_bind_resource(struct monitor_command *cmd, struct resource *res); +void monitor_command_unbind_resource(struct monitor_command *cmd); +int monitor_command_init(struct monitor_command **cmd); +void monitor_command_exit(struct monitor_command *cmd); + +#endif diff --git a/src/monitor/monitor-command.c b/src/monitor/monitor-command.c new file mode 100644 index 0000000..6009ee3 --- /dev/null +++ b/src/monitor/monitor-command.c @@ -0,0 +1,104 @@ +/* + * PASS (Power Aware System Service) + * + * Copyright (c) 2022 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 +#include +#include + +static void _monitor_command_wait_done(struct monitor_command *cmd, int polling) +{ + while (!cmd->done) { + smp_rmb(); + if (polling-- <= 0) { + mtx_lock(&cmd->lock); + cnd_wait(&cmd->signal, &cmd->lock); + mtx_unlock(&cmd->lock); + /* done at this time */ + break; + } + } +} + +void monitor_command_wait_done(struct monitor_command *cmd) +{ + _monitor_command_wait_done(cmd, 0); +} + +void monitor_command_submit(struct monitor_command *cmd) +{ + struct monitor *monitor = monitor_get(); + + cmd->done = false; + enqueue(monitor->q, (void *)cmd); + + cnd_signal(&monitor->signal); +} + +void monitor_command_submit_sync(struct monitor_command *cmd) +{ + monitor_command_submit(cmd); + _monitor_command_wait_done(cmd, MONITOR_POLLING_DURATION); +} + +void monitor_command_bind_resource(struct monitor_command *cmd, struct resource *res) +{ + if (cmd->resource) { + _E("resource is already bound\n"); + return; + } + + cmd->resource = res; +} + +void monitor_command_unbind_resource(struct monitor_command *cmd) +{ + if (!cmd->resource) { + _E("resource is not bound yet\n"); + return; + } + + cmd->resource = NULL; +} + +int monitor_command_init(struct monitor_command **cmd) +{ + struct monitor_command *new_cmd; + + new_cmd = calloc(1, sizeof(struct monitor_command)); + if (!new_cmd) + return -ENOMEM; + + mtx_init(&new_cmd->lock, mtx_plain); + cnd_init(&new_cmd->signal); + new_cmd->done = false; + + *cmd = new_cmd; + + return 0; +} + +void monitor_command_exit(struct monitor_command *cmd) +{ + cnd_destroy(&cmd->signal); + mtx_destroy(&cmd->lock); + + if (cmd->resource) + _W("resource is not unbound before destroying request\n"); + + free(cmd); +} diff --git a/src/monitor/monitor-thread.c b/src/monitor/monitor-thread.c new file mode 100644 index 0000000..e8a3b12 --- /dev/null +++ b/src/monitor/monitor-thread.c @@ -0,0 +1,99 @@ +/* + * PASS (Power Aware System Service) + * + * Copyright (c) 2022 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 +#include + +thread_local int empty_counter = 0; + +static int monitor_func(void *data, void **result) +{ + struct monitor *monitor = data; + struct monitor_command *cmd; + +new_command: + if (dequeue(monitor->q, (void *)&cmd) < 0) { + if (empty_counter++ > MONITOR_POLLING_DURATION) { + empty_counter = 0; + mtx_lock(&monitor->lock); + cnd_wait(&monitor->signal, &monitor->lock); + mtx_unlock(&monitor->lock); + goto new_command; + } + return THREAD_RETURN_CONTINUE; + } + + update_resource_attrs(cmd->resource); + + cmd->done = true; + smp_wmb(); + + cnd_signal(&cmd->signal); + + return THREAD_RETURN_CONTINUE; +} + +int monitor_thread_init(struct monitor *monitor) +{ + struct thread *thread; + struct queue *queue; + int ret; + + ret = create_queue(&queue); + if (ret < 0) { + _E("failed to create command queue\n"); + return ret; + } + + /* q should be assigned before create daemon thread */ + monitor->q = queue; + monitor->priv = NULL; + mtx_init(&monitor->lock, mtx_plain); + cnd_init(&monitor->signal); + + ret = create_daemon_thread(&thread, monitor_func, monitor); + if (ret < 0) { + _E("failed to create monitor thread\n"); + cnd_destroy(&monitor->signal); + mtx_destroy(&monitor->lock); + destroy_queue(queue); + monitor->q = NULL; + return ret; + } + + monitor->thread = thread; + + return 0; +} + +void monitor_thread_exit(struct monitor *monitor) +{ + if (monitor->thread) { + cnd_signal(&monitor->signal); + destroy_thread(monitor->thread); + monitor->thread = NULL; + } + + cnd_destroy(&monitor->signal); + mtx_destroy(&monitor->lock); + + if (monitor->q) { + destroy_queue(monitor->q); + monitor->q = NULL; + } +} diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c new file mode 100644 index 0000000..50f602c --- /dev/null +++ b/src/monitor/monitor.c @@ -0,0 +1,84 @@ +/* + * 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 + +#include +#include +#include +#include + +static struct monitor g_monitor; + +struct monitor *monitor_get(void) +{ + return &g_monitor; +} + +static int monitor_setup(void *data, void *user_data) +{ + int ret; + + ret = monitor_thread_init(&g_monitor); + if (ret < 0) { + _E("failed to initialize monitor thread\n"); + return ret; + } + + return 0; +} + +static void monitor_init(void *data) +{ + /* This is the case of daemon creation: DO NOTHING */ +} + +static void monitor_exit(void *data) +{ + monitor_thread_exit(&g_monitor); + unregister_notifier(DEVICE_NOTIFIER_INIT_DONE, monitor_setup, NULL); +} + +static int monitor_probe(void *data) +{ + int ret = 0; + + /* + * Register a notifier for the booting-done event. The actual + * initialization of the daemon is performed by this notifier after + * booting is completely done. + */ + ret = register_notifier(DEVICE_NOTIFIER_INIT_DONE, + monitor_setup, NULL); + if (ret < 0) { + _E("cannot register a callback function \ + for the booting-done event (%d)\n", ret); + return ret; + } + + return 0; +} + +static const struct device_ops monitor_device_ops = { + .name = "monitor", + .probe = monitor_probe, + .init = monitor_init, + .exit = monitor_exit, +}; + +DEVICE_OPS_REGISTER(&monitor_device_ops) -- 2.7.4 From 19694165bd677fbc677c8d5f4fbdb1cf59f4e37e Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 8 Feb 2022 12:08:46 +0900 Subject: [PATCH 11/16] util: gdbus-util: Fix memory leak issue Change-Id: I3df1d2edbeec17f14cf87ee55065922e0362ba5f Reported-by: Seung-Woo Kim Suggested-by: Seung-Woo Kim Signed-off-by: Chanwoo Choi --- src/util/gdbus-util.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util/gdbus-util.c b/src/util/gdbus-util.c index 53d6da9..b4fcafe 100644 --- a/src/util/gdbus-util.c +++ b/src/util/gdbus-util.c @@ -157,6 +157,7 @@ int pass_gdbus_send_broadcast_signal(passdbus idx, char *path, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &err); if (!ret) { _E("failed to broadcast [%s]", method); + g_error_free(err); g_object_unref(message); return -ECOMM; } -- 2.7.4 From 04e9e50c6ed95e3128ea2f195a34ddcc3fb3d7a0 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 8 Feb 2022 16:19:19 +0900 Subject: [PATCH 12/16] util: gdbus: Rename gdbus-util functions by removing the specific module name Rename gdbus-util functions by removing the specific module name without any behavior changes. Change-Id: I5d0265a985443a628d1265c371c444686ba7d88e Signed-off-by: Chanwoo Choi --- include/util/gdbus-util.h | 38 +++++++++++++++++++------------------- src/main.c | 6 +++--- src/pass/pass.c | 16 ++++++++-------- src/pmqos/pmqos.c | 16 ++++++++-------- src/thermal/thermal.c | 26 +++++++++++++------------- src/util/gdbus-util.c | 34 +++++++++++++++++----------------- 6 files changed, 68 insertions(+), 68 deletions(-) diff --git a/include/util/gdbus-util.h b/include/util/gdbus-util.h index 2f8e078..a5dbc44 100644 --- a/include/util/gdbus-util.h +++ b/include/util/gdbus-util.h @@ -29,34 +29,34 @@ #include "gdbus-definition.h" -struct pass_gdbus_signal_info { +struct gdbus_signal_info { const gchar *handler; GCallback cb; gpointer cb_data; gulong ret_id; }; -int pass_gdbus_register_systemd_startup_callback(GDBusSignalCallback cb, +int gdbus_register_systemd_startup_callback(GDBusSignalCallback cb, gpointer user_data, guint *id); -int pass_gdbus_unregister_systemd_startup_callback(guint id); -int pass_gdbus_get_systemd_dbus_property_string(const char *iface, +int gdbus_unregister_systemd_startup_callback(guint id); +int gdbus_get_systemd_dbus_property_string(const char *iface, const char *prop, const char **value); -int pass_gdbus_export_interface(passdbus idx, gpointer instance, const char *obj_path); -int pass_gdbus_get_name(passdbus idx, const char *name); -int pass_gdbus_connect_signal(gpointer instance, int num_signals, - struct pass_gdbus_signal_info *signal_infos); -void pass_gdbus_disconnect_signal(gpointer instance, int num_signals, - struct pass_gdbus_signal_info *signal_infos); -int pass_gdbus_send_broadcast_signal(passdbus idx, char *path, char *interface, +int gdbus_export_interface(passdbus idx, gpointer instance, const char *obj_path); +int gdbus_get_name(passdbus idx, const char *name); +int gdbus_connect_signal(gpointer instance, int num_signals, + struct gdbus_signal_info *signal_infos); +void gdbus_disconnect_signal(gpointer instance, int num_signals, + struct gdbus_signal_info *signal_infos); +int gdbus_send_broadcast_signal(passdbus idx, char *path, char *interface, char *method, GVariant *arg); -SystemPassCore *pass_gdbus_get_instance_core(void); -void pass_gdbus_put_instance_core(SystemPassCore **instance); -SystemPassPmqos *pass_gdbus_get_instance_pmqos(void); -void pass_gdbus_put_instance_pmqos(SystemPassPmqos **instance); -SystemThermal *pass_gdbus_get_instance_thermal(void); -void pass_gdbus_put_instance_thermal(SystemThermal **instance); +SystemPassCore *gdbus_get_instance_core(void); +void gdbus_put_instance_core(SystemPassCore **instance); +SystemPassPmqos *gdbus_get_instance_pmqos(void); +void gdbus_put_instance_pmqos(SystemPassPmqos **instance); +SystemThermal *gdbus_get_instance_thermal(void); +void gdbus_put_instance_thermal(SystemThermal **instance); -int pass_gdbus_get_system_connection(passdbus idx); -void pass_gdbus_put_system_connection(passdbus idx); +int gdbus_get_system_connection(passdbus idx); +void gdbus_put_system_connection(passdbus idx); #endif /* __GDBUS_UTIL_H__ */ diff --git a/src/main.c b/src/main.c index bbcd618..91f925f 100644 --- a/src/main.c +++ b/src/main.c @@ -51,7 +51,7 @@ static int late_init(void) signal(SIGTERM, sig_quit); signal(SIGUSR1, sig_usr1); - ret = pass_gdbus_get_name(PASS_DBUS_CORE, DBUS_PASS_BUS_NAME); + ret = gdbus_get_name(PASS_DBUS_CORE, DBUS_PASS_BUS_NAME); if (ret < 0) return ret; @@ -63,7 +63,7 @@ static int late_init(void) int main(int argc, char **argv) { g_mainloop = g_main_loop_new(NULL, FALSE); - pass_gdbus_get_system_connection(PASS_DBUS_CORE); + gdbus_get_system_connection(PASS_DBUS_CORE); init_timer(); init_devices(NULL); @@ -74,7 +74,7 @@ int main(int argc, char **argv) exit_devices(NULL); exit_timer(); - pass_gdbus_put_system_connection(PASS_DBUS_CORE); + gdbus_put_system_connection(PASS_DBUS_CORE); g_main_loop_unref(g_mainloop); return 0; diff --git a/src/pass/pass.c b/src/pass/pass.c index ac70225..a0c1a6e 100644 --- a/src/pass/pass.c +++ b/src/pass/pass.c @@ -177,7 +177,7 @@ static gboolean dbus_cb_core_stop(SystemPassCore *obj, * and callback function pointer which is executed when receives * the defined signal. */ -static struct pass_gdbus_signal_info g_gdbus_signal_infos[] = { +static struct gdbus_signal_info g_gdbus_signal_infos[] = { { .handler = DBUS_CORE_I_START_HANDLER, .cb = G_CALLBACK(dbus_cb_core_start), @@ -514,9 +514,9 @@ static void pass_exit(void *data) unregister_notifier(DEVICE_NOTIFIER_INIT_DONE, pass_init_done, NULL); - pass_gdbus_disconnect_signal(g_gdbus_instance, + gdbus_disconnect_signal(g_gdbus_instance, ARRAY_SIZE(g_gdbus_signal_infos), g_gdbus_signal_infos); - pass_gdbus_put_instance_core(&g_gdbus_instance); + gdbus_put_instance_core(&g_gdbus_instance); pass_exit_done(); @@ -537,14 +537,14 @@ static int pass_probe(void *data) g_pass.state = PASS_OFF; - g_gdbus_instance = pass_gdbus_get_instance_core(); + g_gdbus_instance = gdbus_get_instance_core(); if (g_gdbus_instance == NULL) { _E("cannot get a dbus instance for the %s interface\n", DBUS_CORE_INTERFACE); return -ENOSYS; } - ret = pass_gdbus_connect_signal(g_gdbus_instance, + ret = gdbus_connect_signal(g_gdbus_instance, ARRAY_SIZE(g_gdbus_signal_infos), g_gdbus_signal_infos); if (ret < 0) { _E("cannot register callbacks as the dbus method invocation " @@ -553,7 +553,7 @@ static int pass_probe(void *data) goto out; } - ret = pass_gdbus_export_interface(PASS_DBUS_CORE, + ret = gdbus_export_interface(PASS_DBUS_CORE, g_gdbus_instance, DBUS_CORE_PATH); if (ret < 0) { _E("cannot export the dbus interface '%s' " @@ -580,10 +580,10 @@ static int pass_probe(void *data) return 0; out_disconnect: - pass_gdbus_disconnect_signal(g_gdbus_instance, + gdbus_disconnect_signal(g_gdbus_instance, ARRAY_SIZE(g_gdbus_signal_infos), g_gdbus_signal_infos); out: - pass_gdbus_put_instance_core(&g_gdbus_instance); + gdbus_put_instance_core(&g_gdbus_instance); return ret; } diff --git a/src/pmqos/pmqos.c b/src/pmqos/pmqos.c index 404b9ca..91476c6 100644 --- a/src/pmqos/pmqos.c +++ b/src/pmqos/pmqos.c @@ -241,7 +241,7 @@ static gboolean dbus_cb_pmqos_legacy_scenario(SystemPassPmqos *obj, * feature. It contains the signal name and callback function * pointer which is executed when receives the defined signal. */ -static struct pass_gdbus_signal_info g_gdbus_signal_infos[] = { +static struct gdbus_signal_info g_gdbus_signal_infos[] = { { .handler = DBUS_PMQOS_I_APPLAUNCH_HANDLER, .cb = G_CALLBACK(dbus_cb_pmqos_legacy_scenario), @@ -596,9 +596,9 @@ static void pmqos_exit(void *data) unregister_notifier(DEVICE_NOTIFIER_INIT_DONE, pmqos_init_done, NULL); - pass_gdbus_disconnect_signal(g_gdbus_instance, + gdbus_disconnect_signal(g_gdbus_instance, ARRAY_SIZE(g_gdbus_signal_infos), g_gdbus_signal_infos); - pass_gdbus_put_instance_pmqos(&g_gdbus_instance); + gdbus_put_instance_pmqos(&g_gdbus_instance); pmqos_free(); } @@ -615,14 +615,14 @@ static int pmqos_probe(void *data) { int ret = 0; - g_gdbus_instance = pass_gdbus_get_instance_pmqos(); + g_gdbus_instance = gdbus_get_instance_pmqos(); if (!g_gdbus_instance) { _E("cannot get a dbus instance for the %s interface\n", DBUS_PMQOS_INTERFACE); return -ENOSYS; } - ret = pass_gdbus_connect_signal(g_gdbus_instance, + ret = gdbus_connect_signal(g_gdbus_instance, ARRAY_SIZE(g_gdbus_signal_infos), g_gdbus_signal_infos); if (ret < 0) { _E("cannot register callbacks as the dbus method invocation " @@ -631,7 +631,7 @@ static int pmqos_probe(void *data) goto out; } - ret = pass_gdbus_export_interface(PASS_DBUS_CORE, + ret = gdbus_export_interface(PASS_DBUS_CORE, g_gdbus_instance, DBUS_PMQOS_PATH); if (ret < 0) { _E("cannot export the dbus interface '%s' " @@ -658,10 +658,10 @@ static int pmqos_probe(void *data) return 0; out_disconnect: - pass_gdbus_disconnect_signal(g_gdbus_instance, + gdbus_disconnect_signal(g_gdbus_instance, ARRAY_SIZE(g_gdbus_signal_infos), g_gdbus_signal_infos); out: - pass_gdbus_put_instance_pmqos(&g_gdbus_instance); + gdbus_put_instance_pmqos(&g_gdbus_instance); return ret; diff --git a/src/thermal/thermal.c b/src/thermal/thermal.c index 037e84a..60440ab 100644 --- a/src/thermal/thermal.c +++ b/src/thermal/thermal.c @@ -246,7 +246,7 @@ static gboolean dbus_cb_thermal_stop(SystemThermal *obj, * function pointer which is executed when receives the defined * signal. */ -static struct pass_gdbus_signal_info g_gdbus_signal_infos[] = { +static struct gdbus_signal_info g_gdbus_signal_infos[] = { { .handler = DBUS_THERMAL_I_START_HANDLER, .cb = G_CALLBACK(dbus_cb_thermal_start), @@ -381,7 +381,7 @@ static int thermal_notifier_cb(void *data, void *user_data) /* If there is available thermal scenario, send the broadcast signal */ gvar = g_variant_new("(s)", scenario); - ret = pass_gdbus_send_broadcast_signal(PASS_DBUS_THERMAL, + ret = gdbus_send_broadcast_signal(PASS_DBUS_THERMAL, DBUS_THERMAL_PATH, DBUS_THERMAL_INTERFACE, DBUS_THERMAL_SIGNAL, @@ -419,11 +419,11 @@ static void thermal_exit(void *data) unregister_notifier(DEVICE_NOTIFIER_INIT_DONE, thermal_init_done, NULL); - pass_gdbus_disconnect_signal(g_gdbus_instance, + gdbus_disconnect_signal(g_gdbus_instance, ARRAY_SIZE(g_gdbus_signal_infos), g_gdbus_signal_infos); - pass_gdbus_put_instance_thermal(&g_gdbus_instance); + gdbus_put_instance_thermal(&g_gdbus_instance); - pass_gdbus_put_system_connection(PASS_DBUS_THERMAL); + gdbus_put_system_connection(PASS_DBUS_THERMAL); thermal_free(); } @@ -440,14 +440,14 @@ static int thermal_probe(void *data) { int ret = 0; - ret = pass_gdbus_get_system_connection(PASS_DBUS_THERMAL); + ret = gdbus_get_system_connection(PASS_DBUS_THERMAL); if (ret < 0) { _E("Failed to get system connection for thermal"); return -ENOENT; } /* Initialize the d-bus interface for Thermal Monitor */ - g_gdbus_instance = pass_gdbus_get_instance_thermal(); + g_gdbus_instance = gdbus_get_instance_thermal(); if (!g_gdbus_instance) { _E("failed to get a dbus instance for the %s interface\n", DBUS_THERMAL_INTERFACE); @@ -455,14 +455,14 @@ static int thermal_probe(void *data) goto out; } - ret = pass_gdbus_get_name(PASS_DBUS_THERMAL, DBUS_THERMAL_BUS_NAME); + ret = gdbus_get_name(PASS_DBUS_THERMAL, DBUS_THERMAL_BUS_NAME); if (ret < 0) { _E("Failed to own dbus name '%s'\n", DBUS_THERMAL_BUS_NAME); ret = -EINVAL; goto out; } - ret = pass_gdbus_connect_signal(g_gdbus_instance, + ret = gdbus_connect_signal(g_gdbus_instance, ARRAY_SIZE(g_gdbus_signal_infos), g_gdbus_signal_infos); if (ret < 0) { _E("failed to register callbacks as the dbus method invocation " @@ -471,7 +471,7 @@ static int thermal_probe(void *data) goto out_put_instance; } - ret = pass_gdbus_export_interface(PASS_DBUS_THERMAL, + ret = gdbus_export_interface(PASS_DBUS_THERMAL, g_gdbus_instance, DBUS_THERMAL_PATH); if (ret < 0) { _E("failed to export the dbus interface '%s' " @@ -510,12 +510,12 @@ out_booting_done: unregister_notifier(DEVICE_NOTIFIER_INIT_DONE, thermal_init_done, NULL); out_disconnect: - pass_gdbus_disconnect_signal(g_gdbus_instance, + gdbus_disconnect_signal(g_gdbus_instance, ARRAY_SIZE(g_gdbus_signal_infos), g_gdbus_signal_infos); out_put_instance: - pass_gdbus_put_instance_thermal(&g_gdbus_instance); + gdbus_put_instance_thermal(&g_gdbus_instance); out: - pass_gdbus_put_system_connection(PASS_DBUS_THERMAL); + gdbus_put_system_connection(PASS_DBUS_THERMAL); return ret; } diff --git a/src/util/gdbus-util.c b/src/util/gdbus-util.c index b4fcafe..17c25c2 100644 --- a/src/util/gdbus-util.c +++ b/src/util/gdbus-util.c @@ -26,7 +26,7 @@ static GDBusConnection *g_dbus_sys_conn[PASS_DBUS_MAX] = {NULL, }; static int dbus_name_owned; -int pass_gdbus_export_interface(passdbus idx, gpointer instance, +int gdbus_export_interface(passdbus idx, gpointer instance, const char *obj_path) { gboolean ret; @@ -53,14 +53,14 @@ int pass_gdbus_export_interface(passdbus idx, gpointer instance, return -1; } -static void pass_name_acquired_cb(GDBusConnection *connection, +static void name_acquired_cb(GDBusConnection *connection, const gchar *name, gpointer user_data) { if (++dbus_name_owned == PASS_DBUS_MAX) sd_notify(0, "READY=1"); } -int pass_gdbus_get_name(passdbus idx, const char *name) +int gdbus_get_name(passdbus idx, const char *name) { guint id; @@ -71,15 +71,15 @@ int pass_gdbus_get_name(passdbus idx, const char *name) id = g_bus_own_name_on_connection(g_dbus_sys_conn[idx], name, G_BUS_NAME_OWNER_FLAGS_NONE, - pass_name_acquired_cb, NULL, NULL, NULL); + name_acquired_cb, NULL, NULL, NULL); if (id == 0) return -ENOSYS; return 0; } -int pass_gdbus_connect_signal(gpointer instance, int num_signals, - struct pass_gdbus_signal_info *signal_infos) +int gdbus_connect_signal(gpointer instance, int num_signals, + struct gdbus_signal_info *signal_infos) { int i; unsigned long handler_id; @@ -108,8 +108,8 @@ out_err: return -EINVAL; } -void pass_gdbus_disconnect_signal(gpointer instance, int num_signals, - struct pass_gdbus_signal_info *signal_infos) +void gdbus_disconnect_signal(gpointer instance, int num_signals, + struct gdbus_signal_info *signal_infos) { int i; @@ -122,7 +122,7 @@ void pass_gdbus_disconnect_signal(gpointer instance, int num_signals, } } -int pass_gdbus_send_broadcast_signal(passdbus idx, char *path, +int gdbus_send_broadcast_signal(passdbus idx, char *path, char *interface, char *method, GVariant *arg) { GDBusMessage *message = NULL; @@ -173,37 +173,37 @@ static void put_instance(gpointer *instance) *instance = NULL; } -SystemPassCore *pass_gdbus_get_instance_core(void) +SystemPassCore *gdbus_get_instance_core(void) { return system_pass_core_skeleton_new(); } -void pass_gdbus_put_instance_core(SystemPassCore **instance) +void gdbus_put_instance_core(SystemPassCore **instance) { put_instance((gpointer *)instance); } -SystemPassPmqos *pass_gdbus_get_instance_pmqos(void) +SystemPassPmqos *gdbus_get_instance_pmqos(void) { return system_pass_pmqos_skeleton_new(); } -void pass_gdbus_put_instance_pmqos(SystemPassPmqos **instance) +void gdbus_put_instance_pmqos(SystemPassPmqos **instance) { put_instance((gpointer *)instance); } -SystemThermal *pass_gdbus_get_instance_thermal(void) +SystemThermal *gdbus_get_instance_thermal(void) { return system_thermal_skeleton_new(); } -void pass_gdbus_put_instance_thermal(SystemThermal **instance) +void gdbus_put_instance_thermal(SystemThermal **instance) { put_instance((gpointer *)instance); } -int pass_gdbus_get_system_connection(passdbus idx) +int gdbus_get_system_connection(passdbus idx) { GError *error = NULL; @@ -223,7 +223,7 @@ int pass_gdbus_get_system_connection(passdbus idx) return 0; } -void pass_gdbus_put_system_connection(passdbus idx) +void gdbus_put_system_connection(passdbus idx) { if (idx >= PASS_DBUS_MAX) { _E("Invalid DBUS connection: %d\n", idx); -- 2.7.4 From 4cc60f2bd05b4e8a32b1d6494d277adc0d0a3f5d Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Mon, 7 Feb 2022 21:41:36 +0900 Subject: [PATCH 13/16] util: resource: Remove unnecessary passing user_data parameter Change-Id: Ie867d19c667c3a7a273d31719161d74137d3cf84 Signed-off-by: Dongwoo Lee --- include/util/resource.h | 4 ++-- src/resource/resource-bus.c | 12 ++++++------ src/resource/resource-cpu.c | 16 ++++++++-------- src/resource/resource-gpu.c | 14 +++++++------- src/resource/resource-memory.c | 6 +++--- src/util/resource.c | 2 +- 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/include/util/resource.h b/include/util/resource.h index c4bd599..5c7fd8f 100644 --- a/include/util/resource.h +++ b/include/util/resource.h @@ -52,10 +52,10 @@ struct resource_attribute_value { struct resource_attribute_ops { int (*set)(const struct resource *res, const struct resource_attribute *attr, - const void *data, int count, void *user_data); + const void *data, int count); int (*get)(const struct resource *res, const struct resource_attribute *attr, - void **data, void *user_data); + void **data); }; struct resource_attribute { diff --git a/src/resource/resource-bus.c b/src/resource/resource-bus.c index 826f209..f76f047 100644 --- a/src/resource/resource-bus.c +++ b/src/resource/resource-bus.c @@ -34,7 +34,7 @@ static int bus_get_cur_freq(const struct resource *res, const struct resource_attribute *attr, - void **data, void *user_data) + void **data) { int val; @@ -52,7 +52,7 @@ static int bus_get_cur_freq(const struct resource *res, static int bus_get_min_freq(const struct resource *res, const struct resource_attribute *attr, - void **data, void *user_data) + void **data) { int val; @@ -70,7 +70,7 @@ static int bus_get_min_freq(const struct resource *res, static int bus_get_max_freq(const struct resource *res, const struct resource_attribute *attr, - void **data, void *user_data) + void **data) { int val; @@ -88,7 +88,7 @@ static int bus_get_max_freq(const struct resource *res, static int bus_get_available_min_freq(const struct resource *res, const struct resource_attribute *attr, - void **data, void *user_data) + void **data) { int val; @@ -106,7 +106,7 @@ static int bus_get_available_min_freq(const struct resource *res, static int bus_get_available_max_freq(const struct resource *res, const struct resource_attribute *attr, - void **data, void *user_data) + void **data) { int val; @@ -124,7 +124,7 @@ static int bus_get_available_max_freq(const struct resource *res, static int bus_get_curr_governor(const struct resource *res, const struct resource_attribute *attr, - void **data, void *user_data) + void **data) { char buf[BUFF_MAX]; int val; diff --git a/src/resource/resource-cpu.c b/src/resource/resource-cpu.c index de30d38..8d288f4 100644 --- a/src/resource/resource-cpu.c +++ b/src/resource/resource-cpu.c @@ -34,7 +34,7 @@ static int cpu_get_cur_freq(const struct resource *res, const struct resource_attribute *attr, - void **data, void *user_data) + void **data) { int val; @@ -52,7 +52,7 @@ static int cpu_get_cur_freq(const struct resource *res, static int cpu_get_min_freq(const struct resource *res, const struct resource_attribute *attr, - void **data, void *user_data) + void **data) { int val; @@ -70,7 +70,7 @@ static int cpu_get_min_freq(const struct resource *res, static int cpu_get_max_freq(const struct resource *res, const struct resource_attribute *attr, - void **data, void *user_data) + void **data) { int val; @@ -88,7 +88,7 @@ static int cpu_get_max_freq(const struct resource *res, static int cpu_get_available_min_freq(const struct resource *res, const struct resource_attribute *attr, - void **data, void *user_data) + void **data) { int val; @@ -106,7 +106,7 @@ static int cpu_get_available_min_freq(const struct resource *res, static int cpu_get_available_max_freq(const struct resource *res, const struct resource_attribute *attr, - void **data, void *user_data) + void **data) { int val; @@ -124,7 +124,7 @@ static int cpu_get_available_max_freq(const struct resource *res, static int cpu_get_curr_governor(const struct resource *res, const struct resource_attribute *attr, - void **data, void *user_data) + void **data) { char buf[BUFF_MAX]; int val; @@ -145,14 +145,14 @@ static int cpu_get_curr_governor(const struct resource *res, static int cpu_get_online_cpu(const struct resource *res, const struct resource_attribute *attr, - void **data, void *user_data) + void **data) { return 0; } static int cpu_get_temperature(const struct resource *res, const struct resource_attribute *attr, - void **data, void *user_data) + void **data) { return 0; } diff --git a/src/resource/resource-gpu.c b/src/resource/resource-gpu.c index 87acc82..e7afa19 100644 --- a/src/resource/resource-gpu.c +++ b/src/resource/resource-gpu.c @@ -34,7 +34,7 @@ static int gpu_get_cur_freq(const struct resource *res, const struct resource_attribute *attr, - void **data, void *user_data) + void **data) { int val; @@ -52,7 +52,7 @@ static int gpu_get_cur_freq(const struct resource *res, static int gpu_get_min_freq(const struct resource *res, const struct resource_attribute *attr, - void **data, void *user_data) + void **data) { int val; @@ -70,7 +70,7 @@ static int gpu_get_min_freq(const struct resource *res, static int gpu_get_max_freq(const struct resource *res, const struct resource_attribute *attr, - void **data, void *user_data) + void **data) { int val; @@ -88,7 +88,7 @@ static int gpu_get_max_freq(const struct resource *res, static int gpu_get_available_min_freq(const struct resource *res, const struct resource_attribute *attr, - void **data, void *user_data) + void **data) { int val; @@ -106,7 +106,7 @@ static int gpu_get_available_min_freq(const struct resource *res, static int gpu_get_available_max_freq(const struct resource *res, const struct resource_attribute *attr, - void **data, void *user_data) + void **data) { int val; @@ -124,7 +124,7 @@ static int gpu_get_available_max_freq(const struct resource *res, static int gpu_get_curr_governor(const struct resource *res, const struct resource_attribute *attr, - void **data, void *user_data) + void **data) { char buf[BUFF_MAX]; int val; @@ -145,7 +145,7 @@ static int gpu_get_curr_governor(const struct resource *res, static int gpu_get_temperature(const struct resource *res, const struct resource_attribute *attr, - void **data, void *user_data) + void **data) { return 0; } diff --git a/src/resource/resource-memory.c b/src/resource/resource-memory.c index 5d5742f..b4ef902 100644 --- a/src/resource/resource-memory.c +++ b/src/resource/resource-memory.c @@ -74,7 +74,7 @@ static inline int memory_read_val_from_proc_node(uint32_t val_id) static int memory_get_total_memory(const struct resource *res, const struct resource_attribute *attr, - void **data, void *user_data) + void **data) { int val; @@ -92,7 +92,7 @@ static int memory_get_total_memory(const struct resource *res, static int memory_get_available_memory(const struct resource *res, const struct resource_attribute *attr, - void **data, void *user_data) + void **data) { int val; @@ -110,7 +110,7 @@ static int memory_get_available_memory(const struct resource *res, static int memory_get_free_memory(const struct resource *res, const struct resource_attribute *attr, - void **data, void *user_data) + void **data) { int val; diff --git a/src/util/resource.c b/src/util/resource.c index f3f927e..7bc52a6 100644 --- a/src/util/resource.c +++ b/src/util/resource.c @@ -200,7 +200,7 @@ int update_resource_attr(struct resource *resource, u_int64_t attr_id) if (!attr->ops.get) return -EINVAL; - ret = attr->ops.get(resource, attr, &(attr_value->data), resource->user_data); + ret = attr->ops.get(resource, attr, &(attr_value->data)); if (ret < 0) return ret; -- 2.7.4 From 04c556f10ee88c1b1be7074dd74a22f335a7360e Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Mon, 7 Feb 2022 21:53:50 +0900 Subject: [PATCH 14/16] util: resource: Add init/exit ops for resource driver Change-Id: Ie71a2f7de493f198dc57d9daa0b939b3c9eb8e4b Signed-off-by: Dongwoo Lee --- include/util/resource.h | 7 +++++++ src/util/resource.c | 36 ++++++++++++++++++++++++++++++------ 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/include/util/resource.h b/include/util/resource.h index 5c7fd8f..107c194 100644 --- a/include/util/resource.h +++ b/include/util/resource.h @@ -65,11 +65,17 @@ struct resource_attribute { const struct resource_attribute_ops ops; }; +struct resource_driver_ops { + int (*init)(struct resource *res); + void (*exit)(struct resource *res); +}; + struct resource_driver { const char *name; const int type; const int num_attrs; const struct resource_attribute *attrs; + const struct resource_driver_ops ops; }; struct resource_device { @@ -88,6 +94,7 @@ struct resource { int type; int index; void *user_data; + void *priv; int num_attrs; const struct resource_attribute *attrs; diff --git a/src/util/resource.c b/src/util/resource.c index 7bc52a6..7895213 100644 --- a/src/util/resource.c +++ b/src/util/resource.c @@ -130,11 +130,8 @@ static const struct resource_driver *find_resource_driver(int resource_type) return (struct resource_driver *)node->data; } -void delete_resource(struct resource *resource) +static void do_delete_resource(struct resource *resource) { - if (!resource) - return; - if (!resource->name) free(resource->name); if (!resource->attrs_value) @@ -145,13 +142,32 @@ void delete_resource(struct resource *resource) free(resource); } +void delete_resource(struct resource *resource) +{ + const struct resource_driver *driver = NULL; + + if (!resource) + return; + + driver = find_resource_driver(resource->type); + if (!driver) { + _E("failed to find driver for resource type: %d\n", resource->type); + return; + } + + if (driver->ops.exit) + driver->ops.exit(resource); + + do_delete_resource(resource); +} + struct resource *create_resource(int resource_type, int resource_index, void *user_data) { const struct resource_device *device = NULL; const struct resource_driver *driver = NULL; struct resource *resource = NULL; - int i; + int i, ret; device = find_resource_device(resource_type, resource_index); if (!device) @@ -174,13 +190,21 @@ struct resource *create_resource(int resource_type, int resource_index, resource->attrs_value = calloc(resource->num_attrs, sizeof(*resource->attrs_value)); if (!resource->attrs_value) { - delete_resource(resource); + do_delete_resource(resource); return NULL; } for (i = 0; i < resource->num_attrs; i++) resource->attrs_value[i].type = driver->attrs[i].type; + if (driver->ops.init) { + ret = driver->ops.init(resource); + if (ret < 0) { + do_delete_resource(resource); + return NULL; + } + } + return resource; } -- 2.7.4 From 9a102555ff3fb4fe0b30c1eaaf3af082b246b525 Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Thu, 10 Feb 2022 13:06:19 +0900 Subject: [PATCH 15/16] util: common: Add BIT operation Change-Id: I6db6713364c702e16018bba092fbc39a344fd9d5 Signed-off-by: Dongwoo Lee --- include/util/common.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/util/common.h b/include/util/common.h index 40b75a3..263ceea 100644 --- a/include/util/common.h +++ b/include/util/common.h @@ -93,6 +93,12 @@ typedef unsigned long long uint64; #ifndef USEC_TO_MSEC #define USEC_TO_MSEC(x) ((double)x/1000) #endif +#ifndef BIT +#define BIT(x) (1ULL << x) +#endif +#ifndef BIT32 +#define BIT32(x) (1UL << x) +#endif #ifndef container_of #define container_of(ptr, type, member) ({ \ -- 2.7.4 From 7b559095361b683adf58cbca5299627049d42db9 Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Tue, 8 Feb 2022 19:38:52 +0900 Subject: [PATCH 16/16] util: resource: Bypass checking device for virtual device Change-Id: I07076a0549130d452d82e611011389bd58843d88 Signed-off-by: Dongwoo Lee --- include/util/resource.h | 4 ++++ src/util/resource.c | 25 ++++++++++++++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/include/util/resource.h b/include/util/resource.h index 107c194..c996f7d 100644 --- a/include/util/resource.h +++ b/include/util/resource.h @@ -70,9 +70,13 @@ struct resource_driver_ops { void (*exit)(struct resource *res); }; +/* resource driver flags */ +#define RESOURCE_DRIVER_NO_DEVICE BIT32(1) + struct resource_driver { const char *name; const int type; + const int flags; const int num_attrs; const struct resource_attribute *attrs; const struct resource_driver_ops ops; diff --git a/src/util/resource.c b/src/util/resource.c index 7895213..c71c10b 100644 --- a/src/util/resource.c +++ b/src/util/resource.c @@ -169,21 +169,32 @@ struct resource *create_resource(int resource_type, int resource_index, struct resource *resource = NULL; int i, ret; - device = find_resource_device(resource_type, resource_index); - if (!device) - return NULL; - driver = find_resource_driver(resource_type); if (!driver) return NULL; + if (!(driver->flags & RESOURCE_DRIVER_NO_DEVICE)) { + device = find_resource_device(resource_type, resource_index); + if (!device) { + _E("Not available resource: type: %d, index: %d\n", + resource_type, resource_index); + return NULL; + } + } + resource = calloc(1, sizeof(*resource)); if (!resource) return NULL; - resource->type = device->type; - resource->name = g_strdup(device->name); - resource->index = device->index; + if (device) { + resource->type = device->type; + resource->name = g_strdup(device->name); + resource->index = device->index; + } else { + resource->type = resource_type; + resource->name = g_strdup(driver->name); + resource->index = resource_index; + } resource->user_data = user_data; resource->num_attrs = driver->num_attrs; resource->attrs = driver->attrs; -- 2.7.4