From 78676a0feebbc4a933e7e88cdc086bf03f12decc Mon Sep 17 00:00:00 2001 From: "eunwoo.nam" Date: Thu, 13 Nov 2025 19:12:06 +0900 Subject: [PATCH] apps/examples/power: Add cpu usage 100 test The power consumption is effected by CPU usage. To measure power consumption according to CPU status, Add an app that makes the usage of each CPU 100%. Signed-off-by: eunwoo.nam --- apps/examples/power/power_main.c | 128 ++++++++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 3 deletions(-) diff --git a/apps/examples/power/power_main.c b/apps/examples/power/power_main.c index 7d8fe2d5bd..7080d4b981 100644 --- a/apps/examples/power/power_main.c +++ b/apps/examples/power/power_main.c @@ -32,6 +32,8 @@ #include #include #include +#include +#include #include @@ -46,7 +48,41 @@ ****************************************************************************/ static int is_running; +static volatile int cpu_stress_running; +static int cpu_stress_thread(void *arg) +{ + int cpu_id = (int)arg; + cpu_set_t cpuset; + pthread_t this_thread = pthread_self(); + char thread_name[32]; + clock_t prev = clock(); + clock_t now; + +#ifdef CONFIG_SMP + CPU_ZERO(&cpuset); + CPU_SET(cpu_id, &cpuset); + + if (pthread_setaffinity_np(this_thread, sizeof(cpu_set_t), &cpuset) != 0) { + printf("Failed to set CPU%d affinity for thread\n", cpu_id); + return -1; + } +#endif + snprintf(thread_name, sizeof(thread_name), "cpu_stress%d", cpu_id); + pthread_setname_np(this_thread, thread_name); + printf("CPU stress thread started on CPU%d\n", cpu_id); + + while (cpu_stress_running) { + now = clock(); + if (TICK2SEC(now - prev) > 10) { + printf("CPU%d stress running... %ld\n", cpu_id, now); + prev = now; + } + } + + printf("CPU%d stress thread stopped\n", cpu_id); + return 0; +} static int pm_sleep_test(void *args) { @@ -229,6 +265,59 @@ static int start_pm_test(int argc, char *argv[]) return 0; } +static int start_cpu_stress_test(int argc, char *argv[]) +{ + pthread_t cpu_threads[CONFIG_SMP_NCPUS]; + int cpu_num; + + printf("argc %d\n", argc); + for (int i = 0; i < argc; i++) { + printf("argv %s\n", argv[i]); + } + printf("######################### CPU STRESS TEST START #########################\n"); + printf("Starting CPU stress test to achieve 100%% CPU usage\n"); + + printf("System has %d CPUs available\n", CONFIG_SMP_NCPUS); + + if (argc < 2) { + printf("Creating threads on all %d CPUs\n", CONFIG_SMP_NCPUS); + + for (int i = 0; i < CONFIG_SMP_NCPUS; i++) { + if (pthread_create(&cpu_threads[i], NULL, (pthread_startroutine_t)cpu_stress_thread, (void*)i) < 0) { + printf("Failed to create CPU%d stress thread(errno %d)\n", i, get_errno()); + + for (int j = 0; j < i; j++) { + pthread_cancel(cpu_threads[j]); + } + cpu_stress_running = false; + return -1; + } + } + + for (int i = 0; i < CONFIG_SMP_NCPUS; i++) { + pthread_join(cpu_threads[i], NULL); + } + } else { + cpu_num = atoi(argv[1]); + if (cpu_num < 0 || cpu_num >= CONFIG_SMP_NCPUS) { + printf("Invalid CPU number: %d. Use 0 to %d, or no argument for all CPUs\n", cpu_num, CONFIG_SMP_NCPUS - 1); + cpu_stress_running = false; + return -1; + } + printf("Creating thread on CPU%d only\n", cpu_num); + + if (pthread_create(&cpu_threads[cpu_num], NULL, (pthread_startroutine_t)cpu_stress_thread, (void*)cpu_num) < 0) { + printf("Failed to create CPU%d stress thread(errno %d)\n", cpu_num, get_errno()); + cpu_stress_running = false; + return -1; + } + pthread_join(cpu_threads[cpu_num], NULL); + } + + printf("######################### CPU STRESS TEST END #########################\n"); + return 0; +} + static void help_func(void) { printf("usage: power \n\n"); @@ -240,12 +329,14 @@ static void help_func(void) printf("and it is testing suspending of power managemenet operation and resuming for block ender chipset sleep mode.\n"); printf(" start [options]\t\t Start power management test\n"); printf(" stop \t\t stop power management test\n"); + printf(" cpu start [cpu_num]\t Start CPU stress test (100%% CPU usage)\n"); + printf(" cpu stop \t Stop CPU stress test\n"); printf(" options: -l, --lock-test \t\t Test pm suspend/resume API\n"); printf(" -t, --timed-wakeup [time(ms)]\t\t Test timed wakeup (default 100ms)\n"); printf("\n"); - printf("start and stop are used to control the power management test.\n"); - printf(" suspend \t\t Suspend power management test\n"); - printf(" resume \t\t Start power management test\n"); + printf("suspend and resume are used to control the power management test.\n"); + printf(" suspend \t\t suspend power management test\n"); + printf(" resume \t\t resume power management test\n"); printf("\n"); } @@ -289,6 +380,37 @@ int power_main(int argc, char *argv[]) is_running = false; + } else if (strncmp(argv[1], "cpu", 8) == 0) { + if (argc < 3) { + printf("Usage: power cpu {start|stop} [cpu_num]\n"); + return -1; + } + + if (strncmp(argv[2], "start", 6) == 0) { + if (cpu_stress_running) { + printf("CPU stress test is already running\n"); + return 0; + } + cpu_stress_running = true; + + pid = task_create("cpu_stress_test", 100, 1024, start_cpu_stress_test, argv + 3); + if (pid < 0) { + printf("Fail to create cpu_stress_test task(errno %d)\n", get_errno()); + return -1; + } + + } else if (strncmp(argv[2], "stop", 5) == 0) { + if (!cpu_stress_running) { + printf("CPU stress test is not running\n"); + return 0; + } + + cpu_stress_running = false; + } else { + printf("Invalid cpu subcommand. Use 'start' or 'stop'\n"); + return -1; + } + } else if (strncmp(argv[1], "suspend", 8) == 0 && argc == 3) { _pm_suspend(argv[2]); printf("Done pm suspend domain: %s\n", argv[2]);