From: Unsung Lee Date: Thu, 26 May 2022 08:34:54 +0000 (+0900) Subject: Implement CPU boosting plugin X-Git-Tag: submit/tizen/20220526.112909^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=61715d3e8eb12ce83958a7c22b0d35c7c20d6323;p=platform%2Fcore%2Fapi%2Fresource.git Implement CPU boosting plugin Change-Id: I0234087e4caa9f7dccf9ab7c9f7f3013fb9e1243 Signed-off-by: Unsung Lee --- diff --git a/.gitignore b/.gitignore index 9306ae6..0e94c7f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ cscope.files cscope.out tags +*log +*swp +*swo diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d34813..6629ca7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,28 +1,32 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.16) PROJECT(capi-system-resource) +ADD_DEFINITIONS("-DPLUGIN_PATH=\"${PLUGIN_PATH}\"") + SET(PKG_MODULES - dlog - vconf - capi-base-common - capi-system-info - libsyscommon + dlog + vconf + capi-base-common + capi-system-info + libsyscommon ) +INCLUDE_DIRECTORIES(include) + INCLUDE(FindPkgConfig) pkg_check_modules(${PROJECT_NAME} REQUIRED ${PKG_MODULES}) FOREACH(flag ${${PROJECT_NAME}_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror -fvisibility=hidden") SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=${LIB_INSTALL_DIR}") aux_source_directory(src SOURCES) ADD_LIBRARY(${PROJECT_NAME} SHARED ${SOURCES}) -TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${${PROJECT_NAME}_LDFLAGS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${${PROJECT_NAME}_LDFLAGS} "-ldl") SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES @@ -32,7 +36,6 @@ SET_TARGET_PROPERTIES(${PROJECT_NAME} ) INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR}) - SET(PC_NAME ${PROJECT_NAME}) SET(PC_REQUIRED ${pc_dependents}) SET(PC_LDFLAGS -l${PROJECT_NAME}) @@ -43,3 +46,6 @@ CONFIGURE_FILE( @ONLY ) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) + +ADD_SUBDIRECTORY(src/plugin) +ADD_SUBDIRECTORY(tests) diff --git a/include/common.h b/include/common.h new file mode 100644 index 0000000..19a73f6 --- /dev/null +++ b/include/common.h @@ -0,0 +1,67 @@ +/* MIT License + * + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. */ + +#ifndef __TIZEN_SYSTEM_COMMON_H__ +#define __TIZEN_SYSTEM_COMMON_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#undef LOG_TAG +#define LOG_TAG "CAPI_SYSTEM_RESOURCE" + +#define _D(fmt, args...) SLOGD(fmt, ##args) +#define _E(fmt, args...) SLOGE(fmt, ##args) +#define _I(fmt, args...) SLOGI(fmt, ##args) +#define _W(fmt, args...) SLOGW(fmt, ##args) + +#ifndef __CONSTRUCTOR__ +#define __CONSTRUCTOR__ __attribute__ ((constructor)) +#endif + +#ifndef __DESTRUCTOR__ +#define __DESTRUCTOR__ __attribute__ ((destructor)) +#endif + +#ifndef API +#define API __attribute__ ((visibility ("default"))) +#endif + +typedef enum { + RESOURCE_ERROR_NONE = TIZEN_ERROR_NONE, /**< Success */ + RESOURCE_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ + RESOURCE_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ + RESOURCE_ERROR_NO_DATA = TIZEN_ERROR_NO_DATA, /**< Empty data */ + RESOURCE_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */ + RESOURCE_ERROR_NO_SUCH_FILE = TIZEN_ERROR_NO_SUCH_FILE, /**< No such file */ + RESOURCE_ERROR_NOT_SUPPORTED = TIZEN_ERROR_INVALID_OPERATION /**< Not supported */ +} resource_error_e; + +#ifdef __cplusplus +} +#endif + +#endif // __TIZEN_SYSTEM_COMMON_H__ diff --git a/include/cpu-boosting-type.h b/include/cpu-boosting-type.h new file mode 100644 index 0000000..30dbcdb --- /dev/null +++ b/include/cpu-boosting-type.h @@ -0,0 +1,54 @@ +/* MIT License + * + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. */ + +#ifndef __TIZEN_SYSTEM_CPU_BOOSTING_TYPE_H__ +#define __TIZEN_SYSTEM_CPU_BOOSTING_TYPE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum resource_cpu_boosting_level { + CPU_BOOSTING_LEVEL_NONE = -1, + CPU_BOOSTING_LEVEL_STRONG = 0, + CPU_BOOSTING_LEVEL_MEDIUM, + CPU_BOOSTING_LEVEL_WEAK, + CPU_BOOSTING_LEVEL_END, +} cpu_boosting_level_e; + +typedef struct resource_pid_info { + int pid; + int *tid; + int tid_count; +} resource_pid_t; + +typedef struct resource_cpu_boosting_level_info { + int pid_level; + int *tid_level; + int tid_count; +} cpu_boosting_level_info_t; + +#ifdef __cplusplus +} +#endif + +#endif // __TIZEN_SYSTEM_CPU_BOOSTING_TYPE_H__ diff --git a/include/cpu-boosting.h b/include/cpu-boosting.h index 0328b0a..68988bb 100644 --- a/include/cpu-boosting.h +++ b/include/cpu-boosting.h @@ -20,36 +20,21 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#ifndef __TIZEN_SYSTEM_RESOURCE_H__ -#define __TIZEN_SYSTEM_RESOURCE_H__ +#ifndef __TIZEN_SYSTEM_CPU_BOOSTING_H__ +#define __TIZEN_SYSTEM_CPU_BOOSTING_H__ + +#include "cpu-boosting-type.h" #ifdef __cplusplus extern "C" { #endif -typedef enum resource_cpu_boosting_level { - CPU_BOOSTING_LEVEL_STRONG, - CPU_BOOSTING_LEVEL_MEDIUM, - CPU_BOOSTING_LEVEL_WEAK -} cpu_boosting_level_e; - -typedef struct resource_pid_info { - int pid, - int *tid, - int tid_count -} resource_pid_t; - -typedef struct resource_cpu_boosting_level_info { - int pid_level, - int *tid_level, - int tid_count -} cpu_boosting_level_info_t - /** * @brief Set cpu boosting for the target process (pid/tids). * * @param[in] pid The target process pid/tids \n * If pid.pid is zero and pid.tid is NULL, pid of the calling thread is used. \n + * If pid.pid is zero and pid.tid is not NULL, all tids in the list are used \n * If pid.pid is nonzero, pid.tid and pid.tid_count are ignored. \n * The caller must (de)allocate the buffer in the pid.tid pointer. * @param[in] level The cpu boosting level @@ -64,6 +49,7 @@ int resource_set_cpu_boosting (resource_pid_t pid, cpu_boosting_level_e level, i * * @param[in] pid The target process pid/tids \n * If pid.pid is zero and pid.tid is NULL, pid of the calling thread is used. \n + * If pid.pid is zero and pid.tid is not NULL, all tids in the list are used \n * If pid.pid is nonzero, pid.tid and pid.tid_count are ignored. \n * The caller must (de)allocate the buffer in the pid.tid pointer. * @@ -131,4 +117,4 @@ int resource_unregister_cpu_inheritance_destination (char *dest_process); } #endif -#endif // __TIZEN_SYSTEM_RESOURCE_H__ +#endif // __TIZEN_SYSTEM_CPU_BOOSTING_H__ diff --git a/packaging/capi-system-resource.spec b/packaging/capi-system-resource.spec index fcf6003..9ba758a 100644 --- a/packaging/capi-system-resource.spec +++ b/packaging/capi-system-resource.spec @@ -25,12 +25,33 @@ Requires: %{name} = %{version}-%{release} API library for system resource management and optimization (Devel) %devel_desc +%package plugin +Summary: API plugin library for system resource management and optimization +Requires: %{name} = %{version}-%{release} + +%description plugin +API plugin library + +%package test +Summary: API test for system resource management and optimization +Group: System/Development +Requires: %{name} = %{version}-%{release} + +%description test + + %prep %setup -q %build cp %{SOURCE1} . -%cmake . -DVERSION=%{version} +MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` + +%cmake . -DMAJORVER=${MAJORVER} \ + -DFULLVER=%{version} \ + -DPLUGIN_PATH=%{_libdir} + + %__make %{?jobs:-j%jobs} %install @@ -50,3 +71,13 @@ cp %{SOURCE1} . %license LICENSE.MIT %{_libdir}/pkgconfig/*.pc %{_libdir}/libcapi-system-resource.so + +%files plugin +%manifest %{name}.manifest +%license LICENSE.MIT +%{_libdir}/libcapi-system-resource-plugin.so* + +%files test +%manifest %{name}.manifest +%license LICENSE.MIT +%{_bindir}/capi-system-resource-test diff --git a/src/cpu-boosting.c b/src/cpu-boosting.c index 7cf60be..1acd074 100644 --- a/src/cpu-boosting.c +++ b/src/cpu-boosting.c @@ -20,4 +20,203 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +#include +#include +#include "cpu-boosting.h" +#include "common.h" + +static void *plugin_handle = NULL; + +#define CPU_BOOSTING_PLUGIN_PATH PLUGIN_PATH"/libcapi-system-resource-plugin.so" + +static void open_cpu_boosting_plugin(void) +{ + if (access(CPU_BOOSTING_PLUGIN_PATH, F_OK) != 0) { + _E("[CPU-BOOSTING] Cannot find a plugin file"); + } + else { + plugin_handle = dlopen(CPU_BOOSTING_PLUGIN_PATH, RTLD_NOW); + if (!plugin_handle) + _E("[CPU-BOOSTING] Failed to load %s", CPU_BOOSTING_PLUGIN_PATH); + } +} + +API int resource_set_cpu_boosting (resource_pid_t pid, + cpu_boosting_level_e level, int timeout_msec) +{ + int ret; + int (*func)(resource_pid_t pid, cpu_boosting_level_e level, int timeout_msec) = NULL; + + if (!plugin_handle) + return RESOURCE_ERROR_NO_SUCH_FILE; + + func = dlsym(plugin_handle, "resource_set_cpu_boosting"); + if (!func) { + _E("[CPU-BOOSTING] dlsym failed: %s", dlerror()); + return RESOURCE_ERROR_NOT_SUPPORTED; + } + + ret = func(pid, level, timeout_msec); + if (ret != RESOURCE_ERROR_NONE) + _E("[CPU-BOOSTING] Failed to set CPU boosting"); + else + _D("[CPU-BOOSTING] %s called successfully", __func__); + + return ret; +} + +API int resource_clear_cpu_boosting (resource_pid_t pid) +{ + int ret; + int (*func)(resource_pid_t pid) = NULL; + + if (!plugin_handle) + return RESOURCE_ERROR_NO_SUCH_FILE; + + func = dlsym(plugin_handle, "resource_clear_cpu_boosting"); + if (!func) { + _E("[CPU-BOOSTING] dlsym failed: %s", dlerror()); + return RESOURCE_ERROR_NOT_SUPPORTED; + } + + ret = func(pid); + if (ret != RESOURCE_ERROR_NONE) + _E("[CPU-BOOSTING] Failed to clear CPU boosting"); + else + _D("[CPU-BOOSTING] %s called successfully", __func__); + + return ret; +} + +API int resource_get_cpu_boosting_level (resource_pid_t pid, + cpu_boosting_level_info_t *level) +{ + int ret; + int (*func)(resource_pid_t pid, cpu_boosting_level_info_t *level) = NULL; + + if (!plugin_handle) + return RESOURCE_ERROR_NO_SUCH_FILE; + + func = dlsym(plugin_handle, "resource_get_cpu_boosting_level"); + if (!func) { + _E("[CPU-BOOSTING] dlsym failed: %s", dlerror()); + return RESOURCE_ERROR_NOT_SUPPORTED; + } + + ret = func(pid, level); + if (ret != RESOURCE_ERROR_NONE) + _E("[CPU-BOOSTING] Failed to get CPU boosting info"); + else + _D("[CPU-BOOSTING] %s called successfully", __func__); + + return ret; +} + +API int resource_set_cpu_inheritance (int source_tid, char *dest_process, int timeout_msec) +{ + int ret; + int (*func)(int source_tid, char *dest_process, int timeout_msec) = NULL; + + if (!plugin_handle) + return RESOURCE_ERROR_NO_SUCH_FILE; + + func = dlsym(plugin_handle, "resource_set_cpu_inheritance"); + if (!func) { + _E("[CPU-BOOSTING] dlsym failed: %s", dlerror()); + return RESOURCE_ERROR_NOT_SUPPORTED; + } + + ret = func(source_tid, dest_process, timeout_msec); + if (ret != RESOURCE_ERROR_NONE) + _E("[CPU-BOOSTING] Failed to inherit CPU boosting level"); + else + _D("[CPU-BOOSTING] %s called successfully", __func__); + + return ret; +} + +API int resource_clear_cpu_inheritance (int source_tid, char *dest_process) +{ + int ret; + int (*func)(int source_tid, char *dest_process) = NULL; + + if (!plugin_handle) + return RESOURCE_ERROR_NO_SUCH_FILE; + + func = dlsym(plugin_handle, "resource_clear_cpu_inheritance"); + if (!func) { + _E("[CPU-BOOSTING] dlsym failed: %s", dlerror()); + return RESOURCE_ERROR_NOT_SUPPORTED; + } + + ret = func(source_tid, dest_process); + if (ret != RESOURCE_ERROR_NONE) + _E("[CPU-BOOSTING] Failed to cancel CPU boosting inheritance"); + else + _D("[CPU-BOOSTING] %s called successfully", __func__); + + return ret; +} + +API int resource_register_cpu_inheritance_destination (char *dest_process, resource_pid_t pid) +{ + int ret; + int (*func)(char *dest_process, resource_pid_t pid) = NULL; + + if (!plugin_handle) + return RESOURCE_ERROR_NO_SUCH_FILE; + + func = dlsym(plugin_handle, "resource_register_cpu_inheritance_destination"); + if (!func) { + _E("[CPU-BOOSTING] dlsym failed: %s", dlerror()); + return RESOURCE_ERROR_NOT_SUPPORTED; + } + + ret = func(dest_process, pid); + if (ret != RESOURCE_ERROR_NONE) + _E("[CPU-BOOSTING] Failed to register a destination"); + else + _D("[CPU-BOOSTING] %s called successfully", __func__); + + return ret; +} + +API int resource_unregister_cpu_inheritance_destination (char *dest_process) +{ + int ret; + int (*func)(char *dest_process) = NULL; + + if (!plugin_handle) + return RESOURCE_ERROR_NO_SUCH_FILE; + + func = dlsym(plugin_handle, "resource_unregister_cpu_inheritance_destination"); + if (!func) { + _E("[CPU-BOOSTING] dlsym failed: %s", dlerror()); + return RESOURCE_ERROR_NOT_SUPPORTED; + } + + ret = func(dest_process); + if (ret != RESOURCE_ERROR_NONE) + _E("[CPU-BOOSTING] Failed to unregister a destination"); + else + _D("[CPU-BOOSTING] %s called successfully", __func__); + + return ret; +} + +static void __CONSTRUCTOR__ cpu_boosting_init(void) +{ + open_cpu_boosting_plugin(); + if (!plugin_handle) + _E("[CPU-BOOSTING] Failed to open CPU boosting plugin"); + else + _D("[CPU-BOOSTING] plugin handle (open) = %p", plugin_handle); +} + +static void __DESTRUCTOR__ cpu_boosting_exit(void) +{ + _D("[CPU-BOOSTING] plugin handle (close) = %p", plugin_handle); + if (plugin_handle) + dlclose(plugin_handle); +} diff --git a/src/plugin/CMakeLists.txt b/src/plugin/CMakeLists.txt new file mode 100644 index 0000000..78c1c8b --- /dev/null +++ b/src/plugin/CMakeLists.txt @@ -0,0 +1,35 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.16) +PROJECT(capi-system-resource-plugin) + +SET(SOURCES + plugin.c +) + +SET(PKG_MODULES + dlog + vconf + capi-base-common + capi-system-info + libsyscommon +) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) + +INCLUDE(FindPkgConfig) +pkg_check_modules(${PROJECT_NAME} REQUIRED ${PKG_MODULES}) +FOREACH(flag ${${PROJECT_NAME}_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror -fvisibility=hidden") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") + +ADD_LIBRARY(${PROJECT_NAME} SHARED ${SOURCES}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${${PROJECT_NAME}_LDFLAGS}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} + PROPERTIES + VERSION ${FULLVER} + SOVERSION ${MAJORVER} + CLEAN_DIRECT_OUTPUT 1 +) + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR}) diff --git a/src/plugin/plugin.c b/src/plugin/plugin.c new file mode 100644 index 0000000..ecab651 --- /dev/null +++ b/src/plugin/plugin.c @@ -0,0 +1,94 @@ +/* MIT License + * + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. */ + +#include "plugin.h" +#include "cpu-boosting-type.h" + +API int resource_set_cpu_boosting (resource_pid_t pid, + cpu_boosting_level_e level, int timeout_msec) +{ + _D("[CPU-BOOSTING-PLUGIN] %s called", __func__); + for (int i = 0; i < pid.tid_count; i++) { + _D("[CPU-BOOSTING-PLUGIN] pid = %d, tid = %d", pid.pid, pid.tid[i]); + } + + return 0; +} + +API int resource_clear_cpu_boosting (resource_pid_t pid) +{ + _D("[CPU-BOOSTING-PLUGIN] %s called", __func__); + for (int i = 0; i < pid.tid_count; i++) { + _D("[CPU-BOOSTING-PLUGIN] pid = %d, tid = %d", pid.pid, pid.tid[i]); + } + + return 0; +} + +API int resource_get_cpu_boosting_level (resource_pid_t pid, + cpu_boosting_level_info_t *level) +{ + _D("[CPU-BOOSTING-PLUGIN] %s called", __func__); + for (int i = 0; i < pid.tid_count; i++) { + _D("[CPU-BOOSTING-PLUGIN] pid = %d, tid = %d", pid.pid, pid.tid[i]); + } + + return 0; +} + +API int resource_set_cpu_inheritance (int source_tid, char *dest_process, int timeout_msec) +{ + _D("[CPU-BOOSTING-PLUGIN] %s called", __func__); + + return 0; +} + +API int resource_clear_cpu_inheritance (int source_tid, char *dest_process) +{ + _D("[CPU-BOOSTING-PLUGIN] %s called", __func__); + + return 0; +} + +API int resource_register_cpu_inheritance_destination (char *dest_process, resource_pid_t pid) +{ + _D("[CPU-BOOSTING-PLUGIN] %s called", __func__); + + return 0; +} + +API int resource_unregister_cpu_inheritance_destination (char *dest_process) +{ + _D("[CPU-BOOSTING-PLUGIN] %s called", __func__); + + return 0; +} + +void __CONSTRUCTOR__ cpu_boosting_plugin_init(void) +{ + _D("[CPU-BOOSTING-PLUGIN] CPU boosting plugin Module is loaded"); +} + +void __DESTRUCTOR__ cpu_boosting_plugin_exit(void) +{ + _D("[CPU-BOOSTING-PLUGIN] CPU boosting plugin Module is unloaded"); +} diff --git a/src/plugin/plugin.h b/src/plugin/plugin.h new file mode 100644 index 0000000..96c23e1 --- /dev/null +++ b/src/plugin/plugin.h @@ -0,0 +1,54 @@ +/* MIT License + * + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. */ + +#ifndef __TIZEN_SYSTEM_PLUGIN_H__ +#define __TIZEN_SYSTEM_PLUGIN_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#undef LOG_TAG +#define LOG_TAG "CAPI_SYSTEM_RESOURCE_PLUGIN" + +#define _D(fmt, args...) SLOGD(fmt, ##args) +#define _E(fmt, args...) SLOGE(fmt, ##args) +#define _I(fmt, args...) SLOGI(fmt, ##args) +#define _W(fmt, args...) SLOGW(fmt, ##args) + +#ifndef __CONSTRUCTOR__ +#define __CONSTRUCTOR__ __attribute__ ((constructor)) +#endif +#ifndef __DESTRUCTOR__ +#define __DESTRUCTOR__ __attribute__ ((destructor)) +#endif +#ifndef API +#define API __attribute__ ((visibility ("default"))) +#endif + +#ifdef __cplusplus +} +#endif + +#endif // __TIZEN_SYSTEM_COMMON_H__ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..8f78f83 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,27 @@ +SET(test "capi-system-resource-test") + +SET(SOURCES + main.c +) + +SET(PKG_MODULES + dlog + vconf + capi-base-common + capi-system-info + libsyscommon +) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) + +INCLUDE(FindPkgConfig) +pkg_check_modules(${test} REQUIRED ${PKG_MODULES}) +FOREACH(flag ${${test}_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Werror -Wall -pthread") +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -pie") + +ADD_EXECUTABLE(${test} ${SOURCES}) +TARGET_LINK_LIBRARIES(${test} ${PROJECT_NAME} ${test_LDFLAGS} "-ldl") +INSTALL(TARGETS ${test} DESTINATION bin) diff --git a/tests/main.c b/tests/main.c new file mode 100644 index 0000000..77bfccc --- /dev/null +++ b/tests/main.c @@ -0,0 +1,223 @@ +/* MIT License + * + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. */ + +#include +#include +#include +#include +#include +#include + + +#include "common.h" +#include "cpu-boosting.h" + +#define CPU_BOOSTING_API_NUM 7 + +#ifndef gettid +#include + +#ifdef SYS_gettid +#define gettid() (int) syscall(SYS_gettid) +#else +#error "[CPU-BOOSTING-TEST] SYS_gettid unavailable on this system" +#endif + +#endif + +static void *thread_worker(void *arg) +{ + int *tid = (int *)arg; + if (tid) + *tid = gettid(); + + pthread_exit(NULL); +} + +static void test_set_cpu_boosting(resource_pid_t pid, cpu_boosting_level_e level, int timeout_msec) +{ + int ret; + + ret = resource_set_cpu_boosting(pid, level, timeout_msec); + if (ret) { + _E("[CPU-BOOSTING-TEST] error = %d", ret); + } +} + +static void test_clear_cpu_boosting(resource_pid_t pid) +{ + int ret; + + ret = resource_clear_cpu_boosting(pid); + if (ret) { + _E("[CPU-BOOSTING-TEST] error = %d", ret); + } +} + +static void test_get_cpu_boosting(resource_pid_t pid, cpu_boosting_level_info_t *level) +{ + int ret; + + ret = resource_get_cpu_boosting_level(pid, level); + if (ret) { + _E("[CPU-BOOSTING-TEST] error = %d", ret); + } +} + +static void test_cpu_boosting(resource_pid_t pid) +{ + cpu_boosting_level_info_t cur_level; + + for (int level = CPU_BOOSTING_LEVEL_WEAK; level > CPU_BOOSTING_LEVEL_NONE; level--) + test_set_cpu_boosting(pid, level, -1); + + test_get_cpu_boosting(pid, &cur_level); /* Expect CPU_BOOSTING_LEVEL_STRRONG */ + test_clear_cpu_boosting(pid); + test_get_cpu_boosting(pid, &cur_level); /* Expect CPU_BOOSTING_LEVEL_NONE */ +} + +static void one_process_one_thread_test(void) +{ + resource_pid_t pid; + + pid.pid = 0; + pid.tid = NULL; + pid.tid_count = 0; + + test_cpu_boosting(pid); +} + +static void multi_process_one_thread_test(int pid_count) +{ + int status; + pid_t pid, wpid; + + if (pid_count < 1) + return; + + for (int i = 1; i < pid_count; i++) { + pid = fork(); + + /* child */ + if (pid == 0) { + one_process_one_thread_test(); + exit(0); + } + /* parent */ + else if (pid > 0) { + continue; + } + else { + _E("[CPU-BOOSTING-TEST] Failed to fork a new process"); + } + } + + one_process_one_thread_test(); + while ((wpid = wait(&status)) > 0); +} + +static void one_process_multi_thread_test(int tid_count) +{ + int ret; + int real_tid_count = 0; + resource_pid_t pid; + + if (tid_count < 1) + return; + + pid.tid = (int *)calloc(tid_count, sizeof(int)); + if (pid.tid == NULL) { + _E("[CPU-BOOSTING-TEST] Failed to allocate memory for tids"); + return; + } + + for (int i = 0; i < tid_count; i++) { + pthread_t thread; + ret = pthread_create(&thread, NULL, thread_worker, &pid.tid[i]); + if (ret == 0) { + real_tid_count++; + ret = pthread_join(thread, NULL); + if (ret) + _E("[CPU-BOOSTING-TEST] Failed to join a new thread"); + } + else { + _E("[CPU-BOOSTING-TEST] Failed to create a new thread"); + } + } + pid.pid = 0; + pid.tid_count = real_tid_count; + test_cpu_boosting(pid); + free(pid.tid); +} + +static void one_process_all_thread_test(int tid_count) +{ + int ret; + resource_pid_t pid; + + if (tid_count < 1) + return; + + pid.pid = getpid(); + pid.tid = NULL; + pid.tid_count = 0; + + for (int i = 1; i < tid_count; i++) { + pthread_t thread; + ret = pthread_create(&thread, NULL, thread_worker, NULL); + if (ret == 0) { + ret = pthread_join(thread, NULL); + if (ret) + _E("[CPU-BOOSTING-TEST] Failed to join a new thread"); + } + else { + _E("[CPU-BOOSTING-TEST] Failed to create a new thread"); + } + } + test_cpu_boosting(pid); +} + +int main (void) +{ + /* Case 1: Boosting a process with a single thread */ + _D("[CPU-BOOSTING-TEST] <<<<<<<<<< One Process One Thread >>>>>>>>>>"); + one_process_one_thread_test(); + + /* Case 2: Boosting single-threaded processes */ + _D("[CPU-BOOSTING-TEST] <<<<<<<<<< Multi Processes One Thread >>>>>>>>>>"); + multi_process_one_thread_test(7); + + /* Case 3: Boosting a multi-threaded process */ + _D("[CPU-BOOSTING-TEST] <<<<<<<<<< One Process Multi Threads >>>>>>>>>>"); + one_process_multi_thread_test(7); + + /* Case 4: Boosting all threads in a process */ + _D("[CPU-BOOSTING-TEST] <<<<<<<<<< One Process All Threads >>>>>>>>>>"); + one_process_all_thread_test(7); + + /* Case 5: Inheritance to a process with a signle thread */ + /* Case 6: Inheritance to single-threaded processes */ + /* Case 7: Inheritance to a multi-threaded process */ + /* Case 8: Inheritance to all threads in a process */ + + return 0; +}