1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
/*
* Copyright (c) 2006-2024, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-08-10 RV the first version
*/
#include <rtthread.h>
#include "utest.h"
/**
* @brief Threads are automatically balanced across cores.
*
* @note Create multiple threads untied core threads, run them for a while on each core to see
* if the threads are automatically distributed evenly, run for a while to output the threads
* running on each core.
*
* Test Case Name: [smp_assigned_idle_cores]
*
* Test Objectives:
* - Test whether ready threads unbound to cores can be automatically allocated
* - to idle cores under the SMP architecture.
*
* Test Scenarios:
* - Under the SMP architecture, each core spends most of its time running the
* - idle thread after the system starts. At this point, create RT_CPUS_NR-1 cyclic
* - tasks and observe whether these tasks can be evenly distributed across all
* - cores for execution. Since the thread running the utest occupies one core, it
* - is only necessary to observe whether the remaining (RT_CPUS_NR - 1) cores can
* - be allocated the newly created threads and execute them.
*
* Verification Metrics:
* - After running this test case, it is necessary to observe the printed thread
* - list, where all threads created with names from T0 to T(RT_CPUS_NR-2) must
* - be in the running state. RT_CPUS_NR must be greater than or equal to 2.
*
* Dependencies:
* - RT_USING_SMP needs to be enabled.
*
* Expected Results:
* - Print the thread list on the terminal, and observe that T0 to T(RT_CPUS_NR-2)
* - are all in the running state, with the output "[ PASSED ] [ result ] testcase
* - (core.smp_assigned_idle_cores)".
*/
#define THREAD_STACK_SIZE UTEST_THR_STACK_SIZE
#define THREAD_PRIORITY 20
static rt_thread_t threads[RT_CPUS_NR - 1];
static int tick = 0;
static rt_align(sizeof(rt_ubase_t)) int finish_flag = 0;
static int num = 0;
/* thread entry function */
static void thread_entry(void *parameter)
{
int value = *(int *)parameter;
while (1)
{
tick++;
if (tick >= 100 && (finish_flag & (1 << value)) == 0)
{
rt_atomic_or((volatile rt_atomic_t *)&finish_flag, (1 << value));
uassert_true(1);
}
}
}
static void thread_on_idle_core_tc(void)
{
static int params[RT_CPUS_NR] = {0};
char thread_name[8];
int i;
/* Initialise the thread entry parameters */
for (i = 0; i < RT_CPUS_NR; i++)
{
params[i] = i;
}
/* Create RT_CPUS_NR-1 threads and pass the entry parameters for each thread */
for (i = 0; i < RT_CPUS_NR - 1; i++)
{
rt_snprintf(thread_name, sizeof(thread_name), "T%d", i);
threads[i] = rt_thread_create(thread_name, thread_entry, ¶ms[i], THREAD_STACK_SIZE, THREAD_PRIORITY, 20);
if (threads[i] != RT_NULL)
{
uassert_true(1);
rt_thread_startup(threads[i]);
}
}
/* Waiting for test cases to finish */
while (finish_flag != (1<<(RT_CPUS_NR-1))-1);
/* Output the current core running threads */
extern long list_thread(void);
list_thread();
}
static rt_err_t utest_tc_init(void)
{
finish_flag = 0;
tick = 0;
rt_kprintf("[Test case]: created threads are automatically assigned to run on idle cores\r\n");
return RT_EOK;
}
static rt_err_t utest_tc_cleanup(void)
{
for (num = 0; num < RT_CPUS_NR - 1; num++)
{
rt_thread_delete(threads[num]);
}
return RT_EOK;
}
static void testcase(void)
{
UTEST_UNIT_RUN(thread_on_idle_core_tc);
}
UTEST_TC_EXPORT(testcase, "core.smp_assigned_idle_cores", utest_tc_init, utest_tc_cleanup, 10);
|