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
4648 ****************************************************************************/
4749
4850static 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
5187static 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+
232321static 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