cpu-boosting: Make functions for code reusability and readability. 95/319295/2
authorUnsung Lee <unsung.lee@samsung.com>
Wed, 5 Feb 2025 03:09:56 +0000 (12:09 +0900)
committerUnsung Lee <unsung.lee@samsung.com>
Mon, 10 Feb 2025 03:07:08 +0000 (12:07 +0900)
Create some functions that can be used commonly in the file.
It improves code reusability and readability.
Additionally, syscommon_resourced_cpu_boosting_info is only updated by set_cpu_boosting_info().

Added functions are like below:
- is_valid_cpu_boosting_level(): Check validity of cpu boosting level
- update_cpu_sched_of_thread_list(): Update cpu scheduling of threads in a thread list
- set_cpu_boosting_info(): Update members in cpu_boosting_info

Change-Id: I1af9880829d65d13bbf07f9a05b6404ddff0595e
Signed-off-by: Unsung Lee <unsung.lee@samsung.com>
src/resource-optimizer/cpu/cpu-boosting.c

index e5c8b69d31b9727e0eab4bcd98157fb4e0ba191e..54b02b002e6fc660d3d514f311cf22ea7c005759 100644 (file)
@@ -61,17 +61,62 @@ struct cpu_contention_handle_data {
        (_input)->client_input.flags = _flags;                                  \
 }
 
+#define CPU_BOOSTING_INFO_SET_TID                      (1 << 0)
+#define CPU_BOOSTING_INFO_SET_REF_CNT                  (1 << 1)
+#define CPU_BOOSTING_INFO_SET_CPU_BOOSTING_FLAGS       (1 << 2)
+#define CPU_BOOSTING_INFO_SET_GSOURCE_ID               (1 << 3)
+#define CPU_BOOSTING_INFO_SET_LEVEL                    (1 << 4)
+
 static void cpu_boosting_handle_command(
                struct syscommon_resourced_cpu_boosting_input *input);
 
+static int set_cpu_boosting_info(
+               uint32_t cpu_boosting_info_set_flag,
+               struct syscommon_resourced_cpu_boosting_info *cpu_boosting_info,
+               pid_t tid, int ref_cnt,
+               int cpu_boosting_flags, guint *timer_id,
+               cpu_boosting_level_e cpu_boosting_level)
+{
+       if (cpu_boosting_info == NULL) {
+               _E("Failed to set CPU boosting info structure due to null pointer");
+               return RESOURCED_ERROR_INVALID_PARAMETER;
+       }
+
+       if (cpu_boosting_info_set_flag & CPU_BOOSTING_INFO_SET_TID)
+               cpu_boosting_info->tid = tid;
+
+       if (cpu_boosting_info_set_flag & CPU_BOOSTING_INFO_SET_REF_CNT)
+               cpu_boosting_info->ref_cnt = ref_cnt;
+
+       if (cpu_boosting_info_set_flag & CPU_BOOSTING_INFO_SET_CPU_BOOSTING_FLAGS)
+               cpu_boosting_info->cpu_boosting_flags = cpu_boosting_flags;
+
+       if (cpu_boosting_info_set_flag & CPU_BOOSTING_INFO_SET_GSOURCE_ID) {
+               if (timer_id)
+                       cpu_boosting_info->gsource_id = *timer_id;
+               else
+                       cpu_boosting_info->gsource_id = 0;
+       }
+
+       if (cpu_boosting_info_set_flag & CPU_BOOSTING_INFO_SET_LEVEL)
+               cpu_boosting_info->level = cpu_boosting_level;
+
+       return RESOURCED_ERROR_NONE;
+}
+
 static void free_cpu_boosting_info(gpointer data)
 {
        struct syscommon_resourced_cpu_boosting_info *cpu_boosting_info =
                (struct syscommon_resourced_cpu_boosting_info *)data;
+       uint32_t cpu_boosting_info_set_flag = 0;
 
        assert(cpu_boosting_info);
 
-       cpu_boosting_info->ref_cnt--;
+       cpu_boosting_info_set_flag = CPU_BOOSTING_INFO_SET_REF_CNT;
+       set_cpu_boosting_info(cpu_boosting_info_set_flag,
+                       cpu_boosting_info, 0, cpu_boosting_info->ref_cnt - 1,
+                       0, NULL, CPU_BOOSTING_LEVEL_NONE);
+
        if (cpu_boosting_info->ref_cnt == 0)
                free(cpu_boosting_info);
 }
@@ -823,6 +868,19 @@ static int cpu_boosting_enqueue_by_conf(void *data,
        return RESOURCED_ERROR_NONE;
 }
 
+static bool is_valid_cpu_boosting_level(cpu_boosting_level_e cpu_boosting_level)
+{
+       switch (cpu_boosting_level) {
+       case CPU_BOOSTING_LEVEL_STRONG:
+       case CPU_BOOSTING_LEVEL_MEDIUM:
+       case CPU_BOOSTING_LEVEL_WEAK:
+               return true;
+       case CPU_BOOSTING_LEVEL_NONE:
+       default:
+               return false;
+       }
+}
+
 static gboolean cpu_boosting_timeout(gpointer data)
 {
        int fail_cnt = 0;
@@ -858,20 +916,14 @@ static gboolean cpu_boosting_timeout(gpointer data)
                                || cpu_boosting_info->gsource_id != *(input->gsource_id))
                        continue;
 
-               switch (cpu_boosting_info->level) {
-               case CPU_BOOSTING_LEVEL_STRONG:
-               case CPU_BOOSTING_LEVEL_MEDIUM:
-               case CPU_BOOSTING_LEVEL_WEAK:
-                       g_hash_table_remove(
-                                       g_cpu_boosting_info_table[cpu_boosting_info->level],
-                                       &tid_list[i]);
-                       break;
-               case CPU_BOOSTING_LEVEL_NONE:
-               default:
+               if (!is_valid_cpu_boosting_level(cpu_boosting_info->level)) {
                        _E("[CPU-BOOSTING] Unknown cpu boosting level (SIGABT)");
                        assert(0);
                }
 
+               g_hash_table_remove(g_cpu_boosting_info_table[cpu_boosting_info->level],
+                               &tid_list[i]);
+
                if (sched_setattr(tid_list[i],
                                        &cpu_boosting_attr[CPU_BOOSTING_LEVEL_NONE], 0) < 0) {
                        fail_cnt++;
@@ -896,19 +948,21 @@ static void cpu_boosting_find_and_insert_info(pid_t tid,
                cpu_boosting_level_e cpu_boosting_level)
 {
        struct syscommon_resourced_cpu_boosting_info *cpu_boosting_info = NULL;
+       uint32_t cpu_boosting_info_set_flag = 0;
 
-       switch (cpu_boosting_level) {
-       case CPU_BOOSTING_LEVEL_STRONG:
-       case CPU_BOOSTING_LEVEL_MEDIUM:
-       case CPU_BOOSTING_LEVEL_WEAK:
-               break;
-       case CPU_BOOSTING_LEVEL_NONE:
-       default:
+       if (!is_valid_cpu_boosting_level(cpu_boosting_level)) {
                _E("[CPU-BOOSTING] Cannot boosting unknown or none level");
                return;
        }
 
        find_cpu_boosting_info_in_tables(&cpu_boosting_info, &tid);
+
+       cpu_boosting_info_set_flag =
+               CPU_BOOSTING_INFO_SET_TID | CPU_BOOSTING_INFO_SET_REF_CNT |
+               CPU_BOOSTING_INFO_SET_CPU_BOOSTING_FLAGS | CPU_BOOSTING_INFO_SET_GSOURCE_ID |
+               CPU_BOOSTING_INFO_SET_LEVEL;
+
+       /* Case1: No previous CPU boosting on the target thread */
        if (cpu_boosting_info == NULL) {
                cpu_boosting_info = (struct syscommon_resourced_cpu_boosting_info *)
                        calloc(1, sizeof (struct syscommon_resourced_cpu_boosting_info));
@@ -917,12 +971,17 @@ static void cpu_boosting_find_and_insert_info(pid_t tid,
                        return;
                }
 
-               cpu_boosting_info->tid = tid;
-               cpu_boosting_info->ref_cnt = 1;
+               set_cpu_boosting_info(cpu_boosting_info_set_flag, cpu_boosting_info,
+                               tid, 1, cpu_boosting_flags, timer_id, cpu_boosting_level);
 
                g_hash_table_insert(g_cpu_boosting_info_table[cpu_boosting_level],
                                &cpu_boosting_info->tid, cpu_boosting_info);
-       } else if (cpu_boosting_info->level != cpu_boosting_level) {
+
+               return;
+       }
+
+       /* Case2: Previous CPU boosting on the target thread, but different CPU boosting level */
+       if (cpu_boosting_info->level != cpu_boosting_level) {
                /**
                 * Do not free cpu_boosting_info in
                 * g_cpu_boosting_info_table[cpu_boosting_info->level].
@@ -930,58 +989,30 @@ static void cpu_boosting_find_and_insert_info(pid_t tid,
                 * will be reused as a value in another table
                 * (g_cpu_boosting_info_table[cpu_boosting_level]
                 */
-               cpu_boosting_info->ref_cnt++;
-               g_hash_table_remove(
-                               g_cpu_boosting_info_table[cpu_boosting_info->level],
+               set_cpu_boosting_info(cpu_boosting_info_set_flag, cpu_boosting_info,
+                               tid, cpu_boosting_info->ref_cnt + 1, cpu_boosting_flags, timer_id, cpu_boosting_level);
+
+               g_hash_table_remove(g_cpu_boosting_info_table[cpu_boosting_info->level],
                                &cpu_boosting_info->tid);
                g_hash_table_insert(g_cpu_boosting_info_table[cpu_boosting_level],
                                &cpu_boosting_info->tid, cpu_boosting_info);
-       }
-
-       cpu_boosting_info->level = cpu_boosting_level;
 
-       /**
-        * Register cpu_boosting_flags to handle cpu contention and
-        * restore cpu boosting level after solving cpu contention.
-        * For example, if resourced received CPU_BOOSTING_COMMAND_SET command
-        * with CPU_BOOSTING_RESET_ON_FORK, then turn on
-        * CPU_BOOSTING_RESET_ON_FORK flag
-        * when decreasing and restoring cpu boosting level.
-        */
-       cpu_boosting_info->cpu_boosting_flags = cpu_boosting_flags;
+               return;
+       }
 
-       if (timer_id)
-               cpu_boosting_info->gsource_id = *timer_id;
-       else
-               cpu_boosting_info->gsource_id = 0;
+       /* Case3: Previous CPU boosting on the target thread with same CPU boosting level */
+       set_cpu_boosting_info(cpu_boosting_info_set_flag, cpu_boosting_info,
+                       tid, cpu_boosting_info->ref_cnt, cpu_boosting_flags, timer_id, cpu_boosting_level);
 }
 
-static void
-cpu_boosting_set(struct syscommon_resourced_cpu_boosting_input *input)
+static int update_cpu_sched_of_thread_list(int tid_count, int *tid_list,
+               cpu_boosting_flag_e cpu_boosting_flags, cpu_boosting_level_e cpu_boosting_level,
+               int *cpu_boosting_fail_cnt, int *cpu_boosting_success_cnt)
 {
-       guint id = 0;
+       struct sched_attr attr = cpu_boosting_attr[cpu_boosting_level];
        int fail_cnt = 0;
        int success_cnt = 0;
-       struct sched_attr attr;
-       int tid_count = input->client_input.pid.tid_count;
-       int *tid_list = input->client_input.pid.tid;
-       int timeout_msec = input->client_input.timeout_msec;
-       cpu_boosting_level_e cpu_boosting_level = input->client_input.level;
-       cpu_boosting_flag_e cpu_boosting_flags = input->client_input.flags;
 
-       switch (cpu_boosting_level) {
-       case CPU_BOOSTING_LEVEL_STRONG:
-       case CPU_BOOSTING_LEVEL_MEDIUM:
-       case CPU_BOOSTING_LEVEL_WEAK:
-               break;
-       case CPU_BOOSTING_LEVEL_NONE:
-               return;
-       default:
-               _E("[CPU-BOOSTING] Unknown boosting level");
-               return;
-       }
-
-       attr = cpu_boosting_attr[cpu_boosting_level];
        if (cpu_boosting_flags & CPU_BOOSTING_RESET_ON_FORK) {
                _I("[CPU-BOOSTING] Turn on SCHED_RESET_ON_FORK flag");
                attr.sched_policy |= SCHED_RESET_ON_FORK;
@@ -999,9 +1030,37 @@ cpu_boosting_set(struct syscommon_resourced_cpu_boosting_input *input)
                        fail_cnt++;
                        continue;
                }
+
                success_cnt++;
        }
 
+       *cpu_boosting_fail_cnt = fail_cnt;
+       *cpu_boosting_success_cnt = success_cnt;
+
+       return RESOURCED_ERROR_NONE;
+}
+
+static void
+cpu_boosting_set(struct syscommon_resourced_cpu_boosting_input *input)
+{
+       guint id = 0;
+       int fail_cnt = 0;
+       int success_cnt = 0;
+       int tid_count = input->client_input.pid.tid_count;
+       int *tid_list = input->client_input.pid.tid;
+       int timeout_msec = input->client_input.timeout_msec;
+       cpu_boosting_level_e cpu_boosting_level = input->client_input.level;
+       cpu_boosting_flag_e cpu_boosting_flags = input->client_input.flags;
+
+       if (!is_valid_cpu_boosting_level(cpu_boosting_level)) {
+               _E("[CPU-BOOSTING] Unknown boosting level");
+               return;
+       }
+
+       update_cpu_sched_of_thread_list(tid_count, tid_list,
+                       cpu_boosting_flags, cpu_boosting_level,
+                       &fail_cnt, &success_cnt);
+
        if (fail_cnt > 0)
                _W("[CPU-BOOSTING] Boosting success ratio = %d/%d", success_cnt, fail_cnt + success_cnt);