Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2022 Microsoft Corporation
3 : : */
4 : :
5 : : #include <string.h>
6 : :
7 : : #include <rte_thread.h>
8 : : #include <rte_debug.h>
9 : : #include <rte_stdatomic.h>
10 : : #include <rte_pause.h>
11 : :
12 : : #include "test.h"
13 : :
14 [ - + ]: 276 : RTE_LOG_REGISTER(threads_logtype_test, test.threads, INFO);
15 : :
16 : : static RTE_ATOMIC(uint32_t) thread_id_ready;
17 : :
18 : : static uint32_t
19 : 7 : thread_main(void *arg)
20 : : {
21 [ + + ]: 7 : if (arg != NULL)
22 : 3 : *(rte_thread_t *)arg = rte_thread_self();
23 : :
24 : 7 : rte_atomic_store_explicit(&thread_id_ready, 1, rte_memory_order_release);
25 : :
26 [ + + ]: 17448328 : while (rte_atomic_load_explicit(&thread_id_ready, rte_memory_order_acquire) == 1)
27 : : rte_pause();
28 : :
29 : 7 : return 0;
30 : : }
31 : :
32 : : static int
33 : 1 : test_thread_create_join(void)
34 : : {
35 : : rte_thread_t thread_id;
36 : : rte_thread_t thread_main_id;
37 : :
38 : 1 : thread_id_ready = 0;
39 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_create(&thread_id, NULL, thread_main, &thread_main_id) == 0,
40 : : "Failed to create thread.");
41 : :
42 [ + + ]: 3248429 : while (rte_atomic_load_explicit(&thread_id_ready, rte_memory_order_acquire) == 0)
43 : : rte_pause();
44 : :
45 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_equal(thread_id, thread_main_id) != 0,
46 : : "Unexpected thread id.");
47 : :
48 : 1 : rte_atomic_store_explicit(&thread_id_ready, 2, rte_memory_order_release);
49 : :
50 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_join(thread_id, NULL) == 0,
51 : : "Failed to join thread.");
52 : :
53 : : return 0;
54 : : }
55 : :
56 : : static int
57 : 1 : test_thread_create_detach(void)
58 : : {
59 : : rte_thread_t thread_id;
60 : : rte_thread_t thread_main_id;
61 : :
62 : 1 : thread_id_ready = 0;
63 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_create(&thread_id, NULL, thread_main,
64 : : &thread_main_id) == 0, "Failed to create thread.");
65 : :
66 [ + + ]: 6905370 : while (rte_atomic_load_explicit(&thread_id_ready, rte_memory_order_acquire) == 0)
67 : : rte_pause();
68 : :
69 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_equal(thread_id, thread_main_id) != 0,
70 : : "Unexpected thread id.");
71 : :
72 : 1 : rte_atomic_store_explicit(&thread_id_ready, 2, rte_memory_order_release);
73 : :
74 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_detach(thread_id) == 0,
75 : : "Failed to detach thread.");
76 : :
77 : : return 0;
78 : : }
79 : :
80 : : static int
81 : 1 : test_thread_priority(void)
82 : : {
83 : : rte_thread_t thread_id;
84 : : enum rte_thread_priority priority;
85 : :
86 : 1 : thread_id_ready = 0;
87 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_create(&thread_id, NULL, thread_main, NULL) == 0,
88 : : "Failed to create thread");
89 : :
90 [ + + ]: 1299677 : while (rte_atomic_load_explicit(&thread_id_ready, rte_memory_order_acquire) == 0)
91 : : rte_pause();
92 : :
93 : 1 : priority = RTE_THREAD_PRIORITY_NORMAL;
94 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_set_priority(thread_id, priority) == 0,
95 : : "Failed to set thread priority");
96 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_get_priority(thread_id, &priority) == 0,
97 : : "Failed to get thread priority");
98 [ - + ]: 1 : RTE_TEST_ASSERT(priority == RTE_THREAD_PRIORITY_NORMAL,
99 : : "Priority set mismatches priority get");
100 : :
101 : 1 : priority = RTE_THREAD_PRIORITY_REALTIME_CRITICAL;
102 : : #ifndef RTE_EXEC_ENV_WINDOWS
103 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_set_priority(thread_id, priority) == ENOTSUP,
104 : : "Priority set to critical should fail");
105 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_get_priority(thread_id, &priority) == 0,
106 : : "Failed to get thread priority");
107 [ - + ]: 1 : RTE_TEST_ASSERT(priority == RTE_THREAD_PRIORITY_NORMAL,
108 : : "Failed set to critical should have retained normal");
109 : : #else
110 : : RTE_TEST_ASSERT(rte_thread_set_priority(thread_id, priority) == 0,
111 : : "Priority set to critical should succeed");
112 : : RTE_TEST_ASSERT(rte_thread_get_priority(thread_id, &priority) == 0,
113 : : "Failed to get thread priority");
114 : : RTE_TEST_ASSERT(priority == RTE_THREAD_PRIORITY_REALTIME_CRITICAL,
115 : : "Priority set mismatches priority get");
116 : : #endif
117 : :
118 : 1 : priority = RTE_THREAD_PRIORITY_NORMAL;
119 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_set_priority(thread_id, priority) == 0,
120 : : "Failed to set thread priority");
121 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_get_priority(thread_id, &priority) == 0,
122 : : "Failed to get thread priority");
123 [ - + ]: 1 : RTE_TEST_ASSERT(priority == RTE_THREAD_PRIORITY_NORMAL,
124 : : "Priority set mismatches priority get");
125 : :
126 : 1 : rte_atomic_store_explicit(&thread_id_ready, 2, rte_memory_order_release);
127 : :
128 : 1 : return 0;
129 : : }
130 : :
131 : : static int
132 : 1 : test_thread_affinity(void)
133 : : {
134 : : rte_thread_t thread_id;
135 : : rte_cpuset_t cpuset0;
136 : : rte_cpuset_t cpuset1;
137 : :
138 : 1 : thread_id_ready = 0;
139 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_create(&thread_id, NULL, thread_main, NULL) == 0,
140 : : "Failed to create thread");
141 : :
142 [ + + ]: 2140201 : while (rte_atomic_load_explicit(&thread_id_ready, rte_memory_order_acquire) == 0)
143 : : rte_pause();
144 : :
145 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_get_affinity_by_id(thread_id, &cpuset0) == 0,
146 : : "Failed to get thread affinity");
147 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_get_affinity_by_id(thread_id, &cpuset1) == 0,
148 : : "Failed to get thread affinity");
149 [ - + ]: 1 : RTE_TEST_ASSERT(memcmp(&cpuset0, &cpuset1, sizeof(rte_cpuset_t)) == 0,
150 : : "Affinity should be stable");
151 : :
152 : : size_t i;
153 [ + + ]: 1024 : for (i = 1; i < CPU_SETSIZE; i++)
154 [ - + ]: 1023 : if (CPU_ISSET(i, &cpuset0)) {
155 : 0 : CPU_ZERO(&cpuset0);
156 : 0 : CPU_SET(i, &cpuset0);
157 : :
158 : 0 : break;
159 : : }
160 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_set_affinity_by_id(thread_id, &cpuset0) == 0,
161 : : "Failed to set thread affinity");
162 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_get_affinity_by_id(thread_id, &cpuset1) == 0,
163 : : "Failed to get thread affinity");
164 [ - + ]: 1 : RTE_TEST_ASSERT(memcmp(&cpuset0, &cpuset1, sizeof(rte_cpuset_t)) == 0,
165 : : "Affinity should be stable");
166 : :
167 : : return 0;
168 : : }
169 : :
170 : : static int
171 : 1 : test_thread_attributes_affinity(void)
172 : : {
173 : : rte_thread_t thread_id;
174 : : rte_thread_attr_t attr;
175 : : rte_cpuset_t cpuset0;
176 : : rte_cpuset_t cpuset1;
177 : :
178 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_attr_init(&attr) == 0,
179 : : "Failed to initialize thread attributes");
180 : :
181 : 1 : CPU_ZERO(&cpuset0);
182 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_get_affinity_by_id(rte_thread_self(), &cpuset0) == 0,
183 : : "Failed to get thread affinity");
184 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_attr_set_affinity(&attr, &cpuset0) == 0,
185 : : "Failed to set thread attributes affinity");
186 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_attr_get_affinity(&attr, &cpuset1) == 0,
187 : : "Failed to get thread attributes affinity");
188 [ - + ]: 1 : RTE_TEST_ASSERT(memcmp(&cpuset0, &cpuset1, sizeof(rte_cpuset_t)) == 0,
189 : : "Affinity should be stable");
190 : :
191 : 1 : thread_id_ready = 0;
192 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_create(&thread_id, &attr, thread_main, NULL) == 0,
193 : : "Failed to create attributes affinity thread.");
194 : :
195 [ + + ]: 1757095 : while (rte_atomic_load_explicit(&thread_id_ready, rte_memory_order_acquire) == 0)
196 : : rte_pause();
197 : :
198 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_get_affinity_by_id(thread_id, &cpuset1) == 0,
199 : : "Failed to get attributes thread affinity");
200 [ - + ]: 1 : RTE_TEST_ASSERT(memcmp(&cpuset0, &cpuset1, sizeof(rte_cpuset_t)) == 0,
201 : : "Failed to apply affinity attributes");
202 : :
203 : 1 : rte_atomic_store_explicit(&thread_id_ready, 2, rte_memory_order_release);
204 : :
205 : 1 : return 0;
206 : : }
207 : :
208 : : static int
209 : 1 : test_thread_attributes_priority(void)
210 : : {
211 : : rte_thread_t thread_id;
212 : : rte_thread_attr_t attr;
213 : : enum rte_thread_priority priority;
214 : :
215 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_attr_init(&attr) == 0,
216 : : "Failed to initialize thread attributes");
217 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_attr_set_priority(&attr, RTE_THREAD_PRIORITY_NORMAL) == 0,
218 : : "Failed to set thread attributes priority");
219 : :
220 : 1 : thread_id_ready = 0;
221 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_create(&thread_id, &attr, thread_main, NULL) == 0,
222 : : "Failed to create attributes priority thread.");
223 : :
224 [ + + ]: 2656846 : while (rte_atomic_load_explicit(&thread_id_ready, rte_memory_order_acquire) == 0)
225 : : rte_pause();
226 : :
227 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_get_priority(thread_id, &priority) == 0,
228 : : "Failed to get thread priority");
229 [ - + ]: 1 : RTE_TEST_ASSERT(priority == RTE_THREAD_PRIORITY_NORMAL,
230 : : "Failed to apply priority attributes");
231 : :
232 : 1 : rte_atomic_store_explicit(&thread_id_ready, 2, rte_memory_order_release);
233 : :
234 : 1 : return 0;
235 : : }
236 : :
237 : : static int
238 : 1 : test_thread_control_create_join(void)
239 : : {
240 : : rte_thread_t thread_id;
241 : : rte_thread_t thread_main_id;
242 : :
243 : 1 : thread_id_ready = 0;
244 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_create_control(&thread_id, "dpdk-test-thcc",
245 : : thread_main, &thread_main_id) == 0,
246 : : "Failed to create thread.");
247 : :
248 [ - + ]: 1 : while (rte_atomic_load_explicit(&thread_id_ready, rte_memory_order_acquire) == 0)
249 : : rte_pause();
250 : :
251 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_equal(thread_id, thread_main_id) != 0,
252 : : "Unexpected thread id.");
253 : :
254 : 1 : rte_atomic_store_explicit(&thread_id_ready, 2, rte_memory_order_release);
255 : :
256 [ - + ]: 1 : RTE_TEST_ASSERT(rte_thread_join(thread_id, NULL) == 0,
257 : : "Failed to join thread.");
258 : :
259 : : return 0;
260 : : }
261 : :
262 : : static struct unit_test_suite threads_test_suite = {
263 : : .suite_name = "threads autotest",
264 : : .setup = NULL,
265 : : .teardown = NULL,
266 : : .unit_test_cases = {
267 : : TEST_CASE(test_thread_create_join),
268 : : TEST_CASE(test_thread_create_detach),
269 : : TEST_CASE(test_thread_affinity),
270 : : TEST_CASE(test_thread_priority),
271 : : TEST_CASE(test_thread_attributes_affinity),
272 : : TEST_CASE(test_thread_attributes_priority),
273 : : TEST_CASE(test_thread_control_create_join),
274 : : TEST_CASES_END()
275 : : }
276 : : };
277 : :
278 : : static int
279 : 1 : test_threads(void)
280 : : {
281 : 1 : return unit_test_suite_runner(&threads_test_suite);
282 : : }
283 : :
284 : 276 : REGISTER_FAST_TEST(threads_autotest, NOHUGE_OK, ASAN_OK, test_threads);
|