1 /*
2  * Copyright (c) 2006-2024, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2024-08-10     RV           the first version
9  */
10 
11 #include <rtthread.h>
12 #include "utest.h"
13 
14 /**
15  * @brief   Threads are automatically balanced across cores.
16  *
17  * @note    Create multiple threads untied core threads, run them for a while on each core to see
18  *          if the threads are automatically distributed evenly, run for a while to output the threads
19  *          running on each core.
20  */
21 
22 #define THREAD_STACK_SIZE UTEST_THR_STACK_SIZE
23 #define THREAD_PRIORITY   20
24 static rt_thread_t threads[RT_CPUS_NR];
25 static int         tick = 0, finsh_flag = 0;
26 static int                num        = 0;
27 /* thread entry function */
thread_entry(void * parameter)28 static void thread_entry(void *parameter)
29 {
30     while (1)
31     {
32         tick++;
33         if (tick == 100)
34         {
35             /* Output the current core running threads */
36             extern long list_thread(void);
37             list_thread();
38             finsh_flag = 0xA55A;
39             uassert_true(1);
40         }
41         rt_thread_delay(5);
42     }
43 }
44 
thread_on_idle_core_tc(void)45 static void thread_on_idle_core_tc(void)
46 {
47     static int params[RT_CPUS_NR] = {0};
48     char       thread_name[8];
49     int        i;
50 
51     /* Initialise the thread entry parameters */
52     for (i = 0; i < RT_CPUS_NR; i++)
53     {
54         params[i] = i;
55     }
56 
57     /* Create RT_CPUS_NR threads and pass the entry parameters for each thread */
58     for (i = 0; i < RT_CPUS_NR; i++)
59     {
60         rt_snprintf(thread_name, sizeof(thread_name), "T%d", i);
61         threads[i] = rt_thread_create(thread_name, thread_entry, &params[i], THREAD_STACK_SIZE, THREAD_PRIORITY, 20);
62         if (threads[i] != RT_NULL)
63         {
64             uassert_true(1);
65             rt_thread_startup(threads[i]);
66         }
67     }
68     /* Waiting for test cases to finish */
69     while (finsh_flag != 0xA55A);
70 }
71 
utest_tc_init(void)72 static rt_err_t utest_tc_init(void)
73 {
74     rt_kprintf("[Test case]: created threads are automatically assigned to run on idle cores\r\n");
75     return RT_EOK;
76 }
77 
utest_tc_cleanup(void)78 static rt_err_t utest_tc_cleanup(void)
79 {
80     for (num = 0; num < RT_CPUS_NR; num++)
81     {
82         rt_thread_delete(threads[num]);
83     }
84     return RT_EOK;
85 }
86 
testcase(void)87 static void testcase(void)
88 {
89     UTEST_UNIT_RUN(thread_on_idle_core_tc);
90 }
91 UTEST_TC_EXPORT(testcase, "testcases.smp.assigned_idle_cores_tc", utest_tc_init, utest_tc_cleanup, 10);
92