Skip to content

Commit 78676a0

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 78676a0

File tree

1 file changed

+125
-3
lines changed

1 file changed

+125
-3
lines changed

apps/examples/power/power_main.c

Lines changed: 125 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,59 @@ 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 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+
232321
static void help_func(void)
233322
{
234323
printf("usage: power <command> \n\n");
@@ -240,12 +329,14 @@ static void help_func(void)
240329
printf("and it is testing suspending of power managemenet operation and resuming for block ender chipset sleep mode.\n");
241330
printf(" start [options]\t\t Start power management test\n");
242331
printf(" stop \t\t stop power management test\n");
332+
printf(" cpu start [cpu_num]\t Start CPU stress test (100%% CPU usage)\n");
333+
printf(" cpu stop \t Stop CPU stress test\n");
243334
printf(" options: -l, --lock-test \t\t Test pm suspend/resume API\n");
244335
printf(" -t, --timed-wakeup [time(ms)]\t\t Test timed wakeup (default 100ms)\n");
245336
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");
337+
printf("suspend and resume are used to control the power management test.\n");
338+
printf(" suspend <name>\t\t suspend power management test\n");
339+
printf(" resume <name>\t\t resume power management test\n");
249340
printf("\n");
250341
}
251342

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

290381
is_running = false;
291382

383+
} else if (strncmp(argv[1], "cpu", 8) == 0) {
384+
if (argc < 3) {
385+
printf("Usage: power cpu {start|stop} [cpu_num]\n");
386+
return -1;
387+
}
388+
389+
if (strncmp(argv[2], "start", 6) == 0) {
390+
if (cpu_stress_running) {
391+
printf("CPU stress test is already running\n");
392+
return 0;
393+
}
394+
cpu_stress_running = true;
395+
396+
pid = task_create("cpu_stress_test", 100, 1024, start_cpu_stress_test, argv + 3);
397+
if (pid < 0) {
398+
printf("Fail to create cpu_stress_test task(errno %d)\n", get_errno());
399+
return -1;
400+
}
401+
402+
} else if (strncmp(argv[2], "stop", 5) == 0) {
403+
if (!cpu_stress_running) {
404+
printf("CPU stress test is not running\n");
405+
return 0;
406+
}
407+
408+
cpu_stress_running = false;
409+
} else {
410+
printf("Invalid cpu subcommand. Use 'start' or 'stop'\n");
411+
return -1;
412+
}
413+
292414
} else if (strncmp(argv[1], "suspend", 8) == 0 && argc == 3) {
293415
_pm_suspend(argv[2]);
294416
printf("Done pm suspend domain: %s\n", argv[2]);

0 commit comments

Comments
 (0)