Add CPU_BOOSTING_FORCE_RESET_ON_CLEAR flag on resource_set_cpu_boosting() 99/319299/1 accepted/tizen/unified/20250213.151248 accepted/tizen/unified/x/20250218.043753
authorUnsung Lee <unsung.lee@samsung.com>
Mon, 3 Feb 2025 04:26:12 +0000 (13:26 +0900)
committerUnsung Lee <unsung.lee@samsung.com>
Fri, 7 Feb 2025 07:59:31 +0000 (16:59 +0900)
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 <unsung.lee@samsung.com>
include/cpu-boosting-type.h
include/cpu-boosting.h
src/plugin/plugin.c
tests/main.c

index a5e862adaaf7a4df33f73b1637bd6f80ec5e9f15..8c7fcd89342b72d8d79f92e6f0ec6b32679922b9 100644 (file)
@@ -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;
 
 /**
index 20914c52a4f791449b9765d913750e2f20a3c3c3..1c80dc14c1bf35fdf2f2797755ca7e5137b50c00 100644 (file)
@@ -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.
index decd3a50c44e546a80630b0a94946bc50e06c96a..282385dee59717a1491aa01816134267d69192c1 100644 (file)
@@ -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)
index 4d59ae6eed579ab26e68a07b2d30a925c8f40cbc..5c549a67b0e1581052fde574d76d9aa41a5465f7 100644 (file)
@@ -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 >>>>>>>>>>");