Implement CPU boosting plugin 67/275567/6 accepted/tizen/unified/20220528.144338 submit/tizen/20220526.112909
authorUnsung Lee <unsung.lee@samsung.com>
Thu, 26 May 2022 08:34:54 +0000 (17:34 +0900)
committerUnsung Lee <unsung.lee@samsung.com>
Thu, 26 May 2022 11:20:57 +0000 (20:20 +0900)
Change-Id: I0234087e4caa9f7dccf9ab7c9f7f3013fb9e1243
Signed-off-by: Unsung Lee <unsung.lee@samsung.com>
12 files changed:
.gitignore
CMakeLists.txt
include/common.h [new file with mode: 0644]
include/cpu-boosting-type.h [new file with mode: 0644]
include/cpu-boosting.h
packaging/capi-system-resource.spec
src/cpu-boosting.c
src/plugin/CMakeLists.txt [new file with mode: 0644]
src/plugin/plugin.c [new file with mode: 0644]
src/plugin/plugin.h [new file with mode: 0644]
tests/CMakeLists.txt [new file with mode: 0644]
tests/main.c [new file with mode: 0644]

index 9306ae6..0e94c7f 100644 (file)
@@ -1,3 +1,6 @@
 cscope.files
 cscope.out
 tags
+*log
+*swp
+*swo
index 2d34813..6629ca7 100644 (file)
@@ -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 (file)
index 0000000..19a73f6
--- /dev/null
@@ -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 <dlog.h>
+#include <tizen.h>
+
+#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 (file)
index 0000000..30dbcdb
--- /dev/null
@@ -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__
index 0328b0a..68988bb 100644 (file)
  * 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__
index fcf6003..9ba758a 100644 (file)
@@ -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
index 7cf60be..1acd074 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE. */
 
+#include <unistd.h>
+#include <dlfcn.h>
 
+#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 (file)
index 0000000..78c1c8b
--- /dev/null
@@ -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 (file)
index 0000000..ecab651
--- /dev/null
@@ -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 (file)
index 0000000..96c23e1
--- /dev/null
@@ -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 <dlog.h>
+
+#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 (file)
index 0000000..8f78f83
--- /dev/null
@@ -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 (file)
index 0000000..77bfccc
--- /dev/null
@@ -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 <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+
+#include "common.h"
+#include "cpu-boosting.h"
+
+#define CPU_BOOSTING_API_NUM   7
+
+#ifndef gettid
+#include <sys/syscall.h>
+
+#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;
+}