Skip to content

Commit 7522e28

Browse files
committed
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 <[email protected]>
1 parent 8ef7b4a commit 7522e28

File tree

1 file changed

+138
-3
lines changed

1 file changed

+138
-3
lines changed

apps/examples/power/power_main.c

Lines changed: 138 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
#include <unistd.h>
3333
#include <pthread.h>
3434
#include <sys/stat.h>
35+
#include <sched.h>
36+
#include <sys/prctl.h>
3537

3638
#include <tinyara/fs/ioctl.h>
3739

@@ -46,7 +48,41 @@
4648
****************************************************************************/
4749

4850
static int is_running;
51+
static volatile int cpu_stress_running;
4952

53+
static int cpu_stress_thread(void *arg)
54+
{
55+
int cpu_id = (int)arg;
56+
cpu_set_t cpuset;
57+
pthread_t this_thread = pthread_self();
58+
char thread_name[32];
59+
clock_t prev = clock();
60+
clock_t now;
61+
62+
#ifdef CONFIG_SMP
63+
CPU_ZERO(&cpuset);
64+
CPU_SET(cpu_id, &cpuset);
65+
66+
if (pthread_setaffinity_np(this_thread, sizeof(cpu_set_t), &cpuset) != 0) {
67+
printf("Failed to set CPU%d affinity for thread\n", cpu_id);
68+
return -1;
69+
}
70+
#endif
71+
snprintf(thread_name, sizeof(thread_name), "cpu_stress%d", cpu_id);
72+
pthread_setname_np(this_thread, thread_name);
73+
printf("CPU stress thread started on CPU%d\n", cpu_id);
74+
75+
while (cpu_stress_running) {
76+
now = clock();
77+
if (TICK2SEC(now - prev) > 10) {
78+
printf("CPU%d stress running... %ld\n", cpu_id, now);
79+
prev = now;
80+
}
81+
}
82+
83+
printf("CPU%d stress thread stopped\n", cpu_id);
84+
return 0;
85+
}
5086

5187
static int pm_sleep_test(void *args)
5288
{
@@ -229,6 +265,72 @@ static int start_pm_test(int argc, char *argv[])
229265
return 0;
230266
}
231267

268+
static int start_cpu_stress_test(int argc, char *argv[])
269+
{
270+
pthread_t cpu_threads[CONFIG_SMP_NCPUS];
271+
int cpu_num;
272+
273+
printf("argc %d\n", argc);
274+
for (int i = 0; i < argc; i++) {
275+
printf("argv %s\n", argv[i]);
276+
}
277+
printf("######################### CPU STRESS TEST START #########################\n");
278+
printf("Starting CPU stress test to achieve 100%% CPU usage\n");
279+
280+
printf("System has %d CPUs available\n", CONFIG_SMP_NCPUS);
281+
282+
if (argc < 2) {
283+
printf("Creating threads with priority 120 on all %d CPUs\n", CONFIG_SMP_NCPUS);
284+
285+
for (int i = 0; i < CONFIG_SMP_NCPUS; i++) {
286+
if (pthread_create(&cpu_threads[i], NULL, (pthread_startroutine_t)cpu_stress_thread, (void*)i) < 0) {
287+
printf("Failed to create CPU%d stress thread(errno %d)\n", i, get_errno());
288+
289+
for (int j = 0; j < i; j++) {
290+
pthread_cancel(cpu_threads[j]);
291+
}
292+
cpu_stress_running = false;
293+
return -1;
294+
}
295+
}
296+
297+
for (int i = 0; i < CONFIG_SMP_NCPUS; i++) {
298+
pthread_join(cpu_threads[i], NULL);
299+
}
300+
} else {
301+
cpu_num = atoi(argv[1]);
302+
if (cpu_num < 0 || cpu_num >= CONFIG_SMP_NCPUS) {
303+
printf("Invalid CPU number: %d. Use 0 to %d, or no argument for all CPUs\n", cpu_num, CONFIG_SMP_NCPUS - 1);
304+
cpu_stress_running = false;
305+
return -1;
306+
}
307+
printf("Creating thread on CPU%d only\n", cpu_num);
308+
309+
if (pthread_create(&cpu_threads[cpu_num], NULL, (pthread_startroutine_t)cpu_stress_thread, (void*)cpu_num) < 0) {
310+
printf("Failed to create CPU%d stress thread(errno %d)\n", cpu_num, get_errno());
311+
cpu_stress_running = false;
312+
return -1;
313+
}
314+
pthread_join(cpu_threads[cpu_num], NULL);
315+
}
316+
317+
printf("######################### CPU STRESS TEST END #########################\n");
318+
return 0;
319+
}
320+
321+
static int stop_cpu_stress_test(void)
322+
{
323+
if (!cpu_stress_running) {
324+
printf("CPU stress test is not running\n");
325+
return 0;
326+
}
327+
328+
printf("Stopping CPU stress test...\n");
329+
cpu_stress_running = false;
330+
331+
return 0;
332+
}
333+
232334
static void help_func(void)
233335
{
234336
printf("usage: power <command> \n\n");
@@ -240,12 +342,14 @@ static void help_func(void)
240342
printf("and it is testing suspending of power managemenet operation and resuming for block ender chipset sleep mode.\n");
241343
printf(" start [options]\t\t Start power management test\n");
242344
printf(" stop \t\t stop power management test\n");
345+
printf(" cpu start [cpu_num]\t Start CPU stress test (100%% CPU usage)\n");
346+
printf(" cpu stop \t Stop CPU stress test\n");
243347
printf(" options: -l, --lock-test \t\t Test pm suspend/resume API\n");
244348
printf(" -t, --timed-wakeup [time(ms)]\t\t Test timed wakeup (default 100ms)\n");
245349
printf("\n");
246-
printf("start and stop are used to control the power management test.\n");
247-
printf(" suspend <name>\t\t Suspend power management test\n");
248-
printf(" resume <name>\t\t Start power management test\n");
350+
printf("suspend and resume are used to control the power management test.\n");
351+
printf(" suspend <name>\t\t suspend power management test\n");
352+
printf(" resume <name>\t\t resume power management test\n");
249353
printf("\n");
250354
}
251355

@@ -289,6 +393,37 @@ int power_main(int argc, char *argv[])
289393

290394
is_running = false;
291395

396+
} else if (strncmp(argv[1], "cpu", 8) == 0) {
397+
if (argc < 3) {
398+
printf("Usage: power cpu_stress {start|stop} [cpu_num]\n");
399+
return -1;
400+
}
401+
402+
if (strncmp(argv[2], "start", 6) == 0) {
403+
if (cpu_stress_running) {
404+
printf("CPU stress test is already running\n");
405+
return 0;
406+
}
407+
cpu_stress_running = true;
408+
409+
pid = task_create("cpu_stress_test", 100, 1024, start_cpu_stress_test, argv + 3);
410+
if (pid < 0) {
411+
printf("Fail to create cpu_stress_test task(errno %d)\n", get_errno());
412+
return -1;
413+
}
414+
415+
} else if (strncmp(argv[2], "stop", 5) == 0) {
416+
if (!cpu_stress_running) {
417+
printf("CPU stress test is not running\n");
418+
return 0;
419+
}
420+
421+
cpu_stress_running = false;
422+
} else {
423+
printf("Invalid cpu_stress subcommand. Use 'start' or 'stop'\n");
424+
return -1;
425+
}
426+
292427
} else if (strncmp(argv[1], "suspend", 8) == 0 && argc == 3) {
293428
_pm_suspend(argv[2]);
294429
printf("Done pm suspend domain: %s\n", argv[2]);

0 commit comments

Comments
 (0)