From: Unsung Lee Date: Mon, 3 Feb 2025 04:26:12 +0000 (+0900) Subject: Add CPU_BOOSTING_FORCE_RESET_ON_CLEAR flag on resource_set_cpu_boosting() X-Git-Tag: accepted/tizen/unified/20250213.151248^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=323b75ea24c2b737f74d54a73e66905ff63d1cb7;p=platform%2Fcore%2Fapi%2Fresource.git Add CPU_BOOSTING_FORCE_RESET_ON_CLEAR flag on resource_set_cpu_boosting() Add CPU_BOOSTING_FORCE_RESET_ON_CLEAR flag on resource_set_cpu_boosting() function to reset CPU boosting forcely regardless of duplicate resource_set_cpu_boosting() on the same target. Scenario is like below: resource_set_cpu_boosting() with CPU_BOOSTING_FORCE_RESET_ON_CLEAR flag example: A process: set CPU boosting on C process with CPU_BOOSTING_FORCE_RESET_ON_CLEAR flag B process: set CPU boosting on C process A process: clear CPU boosting on C process In this case, CPU boosting on C process must be cleared regardless of previous CPU boosting sets. Change-Id: Ibb104f6e492cae213d0250d746d410f6b1d2eb16 Signed-off-by: Unsung Lee --- diff --git a/include/cpu-boosting-type.h b/include/cpu-boosting-type.h index a5e862a..8c7fcd8 100644 --- a/include/cpu-boosting-type.h +++ b/include/cpu-boosting-type.h @@ -35,6 +35,7 @@ extern "C" { */ typedef enum resource_cpu_boosting_flag { CPU_BOOSTING_RESET_ON_FORK = 0x01, /**< CPU RESET ON FORK */ + CPU_BOOSTING_FORCE_RESET_ON_CLEAR = 0x02, /**< CPU FORCE RESET ON CLEAR */ } cpu_boosting_flag_e; /** diff --git a/include/cpu-boosting.h b/include/cpu-boosting.h index 20914c5..1c80dc1 100644 --- a/include/cpu-boosting.h +++ b/include/cpu-boosting.h @@ -50,6 +50,8 @@ extern "C" { * @param[in] flags The cpu boosting flag bits * If #CPU_BOOSTING_RESET_ON_FORK is set, child processes or threads created by fork() or pthread_create() * do not inherit boosted CPU schedulder and priority from the parent. + * If #CPU_BOOSTING_FORCE_RESET_ON_CLEAR is set, + * reset CPU boosting forcely on resource_clear_cpu_boosting() regardless of duplicate CPU boosting sets. * @param[in] timeout_msec The timeout in milliseconds, -1 to apply boosting permanently * * @return 0 on success, otherwise a negative error value. diff --git a/src/plugin/plugin.c b/src/plugin/plugin.c index decd3a5..282385d 100644 --- a/src/plugin/plugin.c +++ b/src/plugin/plugin.c @@ -96,12 +96,16 @@ static inline bool resource_pid_input_is_valid(resource_pid_t pid) static inline bool resource_cpu_boosting_level_input_is_valid(cpu_boosting_level_e level) { - if (level < CPU_BOOSTING_LEVEL_STRONG || level > CPU_BOOSTING_LEVEL_WEAK) { - _E("[CPU-BOOSTING-PLUGIN] cpu boosting level should be located between %d and %d, but current level = %d", CPU_BOOSTING_LEVEL_STRONG, CPU_BOOSTING_LEVEL_WEAK, level); + switch (level) { + case CPU_BOOSTING_LEVEL_NONE: + case CPU_BOOSTING_LEVEL_STRONG: + case CPU_BOOSTING_LEVEL_MEDIUM: + case CPU_BOOSTING_LEVEL_WEAK: + return true; + default: + _E("[CPU-BOOSTING-PLUGIN] CPU boosting level (%d) is not valid", level); return false; } - - return true; } static int resource_cpu_boosting_send_command (cpu_boosting_input_t input, int sock) diff --git a/tests/main.c b/tests/main.c index 4d59ae6..5c549a6 100644 --- a/tests/main.c +++ b/tests/main.c @@ -215,6 +215,79 @@ static void multi_process_one_thread_test(int pid_count) while ((wpid = wait(&status)) > 0); } +static int test_multi_process_one_thread_force_reset(int pid_count, cpu_boosting_flag_e flags) +{ + int ret; + int status; + pid_t pid; + pid_t wpid; + resource_pid_t resource_pid = {0,}; + cpu_boosting_level_info_t level = {0,}; + + if (pid_count < 1) + return -EINVAL; + + resource_pid.pid = getpid(); + + /* Parent process sets CPU boosting level as CPU_BOOSTING_LEVEL_STRONG */ + test_set_cpu_boosting(resource_pid, CPU_BOOSTING_LEVEL_STRONG, 0, -1); + + for (int i = 1; i < pid_count; i++) { + pid = fork(); + + if (pid == 0) { + /** + * Child sets CPU boosting level of the parent process as CPU_BOOSTING_LEVEL_STRONG. + * After that, child clears CPU boosting level of the parent process. + * In this case, the boosting level of the parent process may not be cleared. + */ + test_set_cpu_boosting(resource_pid, CPU_BOOSTING_LEVEL_STRONG, 0, -1); + exit(0); + } + + if (pid > 0) + continue; + + _W("Cannot make a new process using fork()"); + break; + } + + /* Parent process waits until all child processes are ended. */ + while (1) { + wpid = wait(&status); + if (wpid < 0) + break; + } + + /** + * Parent process forcely resets CPU boosting level as CPU_BOOSTING_LEVEL_NONE, + * when CPU_BOOSTING_FORCE_RESET_ON_CLEAR is set. + */ + test_set_cpu_boosting(resource_pid, CPU_BOOSTING_LEVEL_NONE, flags, -1); + test_clear_cpu_boosting(resource_pid); + ret = resource_get_cpu_boosting_level(resource_pid, &level); + if (ret < 0) { + _E("Failed to get cpu boosting level: ret (%d)", ret); + return ret; + } + + for(int i = 0; i < level.tid_count; i++) { + if (level.tid_level[i] != CPU_BOOSTING_LEVEL_NONE) + _W("The pid (%d) level (%s) is not CPU_BOOSTING_LEVEL_NONE", + resource_pid.pid, + level.tid_level[i] == CPU_BOOSTING_LEVEL_STRONG ? "CPU_BOOSTING_LEVEL_STRONG" : + level.tid_level[i] == CPU_BOOSTING_LEVEL_MEDIUM ? "CPU_BOOSTING_LEVEL_MEDIUM" : + level.tid_level[i] == CPU_BOOSTING_LEVEL_WEAK ? "CPU_BOOSTING_LEVEL_WEAK" : "Unknown"); + } + + if (level.tid_level) { + free(level.tid_level); + level.tid_level = NULL; + } + + return 0; +} + static void one_process_multi_thread_test(int tid_count) { int ret; @@ -280,6 +353,8 @@ static void one_process_all_thread_test(int tid_count) int main (void) { + int ret = 0; + _D("[CPU-BOOSTING-TEST] Start"); /* Case 1: Boosting a process with a single thread */ @@ -293,6 +368,11 @@ int main (void) /* Case 2: Boosting single-threaded processes */ _D("[CPU-BOOSTING-TEST] <<<<<<<<<< Multi Processes One Thread >>>>>>>>>>"); multi_process_one_thread_test(7); + ret = test_multi_process_one_thread_force_reset(7, CPU_BOOSTING_FORCE_RESET_ON_CLEAR); + if (ret < 0) { + _E("Failed to test multi process with CPU_BOOSTING_FORCE_RESET_ON_CLEAR: ret (%d)", ret); + return 1; + } /* Case 3: Boosting a multi-threaded process */ _D("[CPU-BOOSTING-TEST] <<<<<<<<<< One Process Multi Threads >>>>>>>>>>");