xref: /dpdk/app/test/test_threads.c (revision 8f1d23ece06adff5eae9f1b4365bdbbd3abee2b2)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (C) 2022 Microsoft Corporation
3  */
4 
5 #include <string.h>
6 #include <pthread.h>
7 
8 #include <rte_thread.h>
9 #include <rte_debug.h>
10 
11 #include "test.h"
12 
13 RTE_LOG_REGISTER(threads_logtype_test, test.threads, INFO);
14 
15 static uint32_t thread_id_ready;
16 
17 static void *
18 thread_main(void *arg)
19 {
20 	*(rte_thread_t *)arg = rte_thread_self();
21 	__atomic_store_n(&thread_id_ready, 1, __ATOMIC_RELEASE);
22 
23 	while (__atomic_load_n(&thread_id_ready, __ATOMIC_ACQUIRE) == 1)
24 		;
25 
26 	return NULL;
27 }
28 
29 static int
30 test_thread_priority(void)
31 {
32 	pthread_t id;
33 	rte_thread_t thread_id;
34 	enum rte_thread_priority priority;
35 
36 	thread_id_ready = 0;
37 	RTE_TEST_ASSERT(pthread_create(&id, NULL, thread_main, &thread_id) == 0,
38 		"Failed to create thread");
39 
40 	while (__atomic_load_n(&thread_id_ready, __ATOMIC_ACQUIRE) == 0)
41 		;
42 
43 	priority = RTE_THREAD_PRIORITY_NORMAL;
44 	RTE_TEST_ASSERT(rte_thread_set_priority(thread_id, priority) == 0,
45 		"Failed to set thread priority");
46 	RTE_TEST_ASSERT(rte_thread_get_priority(thread_id, &priority) == 0,
47 		"Failed to get thread priority");
48 	RTE_TEST_ASSERT(priority == RTE_THREAD_PRIORITY_NORMAL,
49 		"Priority set mismatches priority get");
50 
51 	priority = RTE_THREAD_PRIORITY_REALTIME_CRITICAL;
52 #ifndef RTE_EXEC_ENV_WINDOWS
53 	RTE_TEST_ASSERT(rte_thread_set_priority(thread_id, priority) == ENOTSUP,
54 		"Priority set to critical should fail");
55 	RTE_TEST_ASSERT(rte_thread_get_priority(thread_id, &priority) == 0,
56 		"Failed to get thread priority");
57 	RTE_TEST_ASSERT(priority == RTE_THREAD_PRIORITY_NORMAL,
58 		"Failed set to critical should have retained normal");
59 #else
60 	RTE_TEST_ASSERT(rte_thread_set_priority(thread_id, priority) == 0,
61 		"Priority set to critical should succeed");
62 	RTE_TEST_ASSERT(rte_thread_get_priority(thread_id, &priority) == 0,
63 		"Failed to get thread priority");
64 	RTE_TEST_ASSERT(priority == RTE_THREAD_PRIORITY_REALTIME_CRITICAL,
65 		"Priority set mismatches priority get");
66 #endif
67 
68 	priority = RTE_THREAD_PRIORITY_NORMAL;
69 	RTE_TEST_ASSERT(rte_thread_set_priority(thread_id, priority) == 0,
70 		"Failed to set thread priority");
71 	RTE_TEST_ASSERT(rte_thread_get_priority(thread_id, &priority) == 0,
72 		"Failed to get thread priority");
73 	RTE_TEST_ASSERT(priority == RTE_THREAD_PRIORITY_NORMAL,
74 		"Priority set mismatches priority get");
75 
76 	__atomic_store_n(&thread_id_ready, 2, __ATOMIC_RELEASE);
77 
78 	return 0;
79 }
80 
81 static int
82 test_thread_affinity(void)
83 {
84 	pthread_t id;
85 	rte_thread_t thread_id;
86 	rte_cpuset_t cpuset0;
87 	rte_cpuset_t cpuset1;
88 
89 	thread_id_ready = 0;
90 	RTE_TEST_ASSERT(pthread_create(&id, NULL, thread_main, &thread_id) == 0,
91 		"Failed to create thread");
92 
93 	while (__atomic_load_n(&thread_id_ready, __ATOMIC_ACQUIRE) == 0)
94 		;
95 
96 	RTE_TEST_ASSERT(rte_thread_get_affinity_by_id(thread_id, &cpuset0) == 0,
97 		"Failed to get thread affinity");
98 	RTE_TEST_ASSERT(rte_thread_get_affinity_by_id(thread_id, &cpuset1) == 0,
99 		"Failed to get thread affinity");
100 	RTE_TEST_ASSERT(memcmp(&cpuset0, &cpuset1, sizeof(rte_cpuset_t)) == 0,
101 		"Affinity should be stable");
102 
103 	size_t i;
104 	for (i = 1; i < CPU_SETSIZE; i++)
105 		if (CPU_ISSET(i, &cpuset0)) {
106 			CPU_ZERO(&cpuset0);
107 			CPU_SET(i, &cpuset0);
108 
109 			break;
110 		}
111 	RTE_TEST_ASSERT(rte_thread_set_affinity_by_id(thread_id, &cpuset0) == 0,
112 		"Failed to set thread affinity");
113 	RTE_TEST_ASSERT(rte_thread_get_affinity_by_id(thread_id, &cpuset1) == 0,
114 		"Failed to get thread affinity");
115 	RTE_TEST_ASSERT(memcmp(&cpuset0, &cpuset1, sizeof(rte_cpuset_t)) == 0,
116 		"Affinity should be stable");
117 
118 	return 0;
119 }
120 
121 static struct unit_test_suite threads_test_suite = {
122 	.suite_name = "threads autotest",
123 	.setup = NULL,
124 	.teardown = NULL,
125 	.unit_test_cases = {
126 		TEST_CASE(test_thread_affinity),
127 		TEST_CASE(test_thread_priority),
128 		TEST_CASES_END()
129 	}
130 };
131 
132 static int
133 test_threads(void)
134 {
135 	return unit_test_suite_runner(&threads_test_suite);
136 }
137 
138 REGISTER_TEST_COMMAND(threads_autotest, test_threads);
139