xref: /dpdk/app/test/test_threads.c (revision 1f16100df168d22e8f53ad98ce1b0f4b912842a9)
104e53de9STyler Retzlaff /* SPDX-License-Identifier: BSD-3-Clause
204e53de9STyler Retzlaff  * Copyright (C) 2022 Microsoft Corporation
304e53de9STyler Retzlaff  */
404e53de9STyler Retzlaff 
504e53de9STyler Retzlaff #include <string.h>
604e53de9STyler Retzlaff #include <pthread.h>
704e53de9STyler Retzlaff 
804e53de9STyler Retzlaff #include <rte_thread.h>
904e53de9STyler Retzlaff #include <rte_debug.h>
1004e53de9STyler Retzlaff 
1104e53de9STyler Retzlaff #include "test.h"
1204e53de9STyler Retzlaff 
1304e53de9STyler Retzlaff RTE_LOG_REGISTER(threads_logtype_test, test.threads, INFO);
1404e53de9STyler Retzlaff 
1504e53de9STyler Retzlaff static uint32_t thread_id_ready;
1604e53de9STyler Retzlaff 
1704e53de9STyler Retzlaff static void *
1804e53de9STyler Retzlaff thread_main(void *arg)
1904e53de9STyler Retzlaff {
2004e53de9STyler Retzlaff 	*(rte_thread_t *)arg = rte_thread_self();
2104e53de9STyler Retzlaff 	__atomic_store_n(&thread_id_ready, 1, __ATOMIC_RELEASE);
2204e53de9STyler Retzlaff 
23*1f16100dSTyler Retzlaff 	while (__atomic_load_n(&thread_id_ready, __ATOMIC_ACQUIRE) == 1)
24*1f16100dSTyler Retzlaff 		;
25*1f16100dSTyler Retzlaff 
2604e53de9STyler Retzlaff 	return NULL;
2704e53de9STyler Retzlaff }
2804e53de9STyler Retzlaff 
2904e53de9STyler Retzlaff static int
30*1f16100dSTyler Retzlaff test_thread_priority(void)
31*1f16100dSTyler Retzlaff {
32*1f16100dSTyler Retzlaff 	pthread_t id;
33*1f16100dSTyler Retzlaff 	rte_thread_t thread_id;
34*1f16100dSTyler Retzlaff 	enum rte_thread_priority priority;
35*1f16100dSTyler Retzlaff 
36*1f16100dSTyler Retzlaff 	thread_id_ready = 0;
37*1f16100dSTyler Retzlaff 	RTE_TEST_ASSERT(pthread_create(&id, NULL, thread_main, &thread_id) == 0,
38*1f16100dSTyler Retzlaff 		"Failed to create thread");
39*1f16100dSTyler Retzlaff 
40*1f16100dSTyler Retzlaff 	while (__atomic_load_n(&thread_id_ready, __ATOMIC_ACQUIRE) == 0)
41*1f16100dSTyler Retzlaff 		;
42*1f16100dSTyler Retzlaff 
43*1f16100dSTyler Retzlaff 	priority = RTE_THREAD_PRIORITY_NORMAL;
44*1f16100dSTyler Retzlaff 	RTE_TEST_ASSERT(rte_thread_set_priority(thread_id, priority) == 0,
45*1f16100dSTyler Retzlaff 		"Failed to set thread priority");
46*1f16100dSTyler Retzlaff 	RTE_TEST_ASSERT(rte_thread_get_priority(thread_id, &priority) == 0,
47*1f16100dSTyler Retzlaff 		"Failed to get thread priority");
48*1f16100dSTyler Retzlaff 	RTE_TEST_ASSERT(priority == RTE_THREAD_PRIORITY_NORMAL,
49*1f16100dSTyler Retzlaff 		"Priority set mismatches priority get");
50*1f16100dSTyler Retzlaff 
51*1f16100dSTyler Retzlaff 	priority = RTE_THREAD_PRIORITY_REALTIME_CRITICAL;
52*1f16100dSTyler Retzlaff #ifndef RTE_EXEC_ENV_WINDOWS
53*1f16100dSTyler Retzlaff 	RTE_TEST_ASSERT(rte_thread_set_priority(thread_id, priority) == ENOTSUP,
54*1f16100dSTyler Retzlaff 		"Priority set to critical should fail");
55*1f16100dSTyler Retzlaff 	RTE_TEST_ASSERT(rte_thread_get_priority(thread_id, &priority) == 0,
56*1f16100dSTyler Retzlaff 		"Failed to get thread priority");
57*1f16100dSTyler Retzlaff 	RTE_TEST_ASSERT(priority == RTE_THREAD_PRIORITY_NORMAL,
58*1f16100dSTyler Retzlaff 		"Failed set to critical should have retained normal");
59*1f16100dSTyler Retzlaff #else
60*1f16100dSTyler Retzlaff 	RTE_TEST_ASSERT(rte_thread_set_priority(thread_id, priority) == 0,
61*1f16100dSTyler Retzlaff 		"Priority set to critical should succeed");
62*1f16100dSTyler Retzlaff 	RTE_TEST_ASSERT(rte_thread_get_priority(thread_id, &priority) == 0,
63*1f16100dSTyler Retzlaff 		"Failed to get thread priority");
64*1f16100dSTyler Retzlaff 	RTE_TEST_ASSERT(priority == RTE_THREAD_PRIORITY_REALTIME_CRITICAL,
65*1f16100dSTyler Retzlaff 		"Priority set mismatches priority get");
66*1f16100dSTyler Retzlaff #endif
67*1f16100dSTyler Retzlaff 
68*1f16100dSTyler Retzlaff 	priority = RTE_THREAD_PRIORITY_NORMAL;
69*1f16100dSTyler Retzlaff 	RTE_TEST_ASSERT(rte_thread_set_priority(thread_id, priority) == 0,
70*1f16100dSTyler Retzlaff 		"Failed to set thread priority");
71*1f16100dSTyler Retzlaff 	RTE_TEST_ASSERT(rte_thread_get_priority(thread_id, &priority) == 0,
72*1f16100dSTyler Retzlaff 		"Failed to get thread priority");
73*1f16100dSTyler Retzlaff 	RTE_TEST_ASSERT(priority == RTE_THREAD_PRIORITY_NORMAL,
74*1f16100dSTyler Retzlaff 		"Priority set mismatches priority get");
75*1f16100dSTyler Retzlaff 
76*1f16100dSTyler Retzlaff 	__atomic_store_n(&thread_id_ready, 2, __ATOMIC_RELEASE);
77*1f16100dSTyler Retzlaff 
78*1f16100dSTyler Retzlaff 	return 0;
79*1f16100dSTyler Retzlaff }
80*1f16100dSTyler Retzlaff 
81*1f16100dSTyler Retzlaff static int
8204e53de9STyler Retzlaff test_thread_affinity(void)
8304e53de9STyler Retzlaff {
8404e53de9STyler Retzlaff 	pthread_t id;
8504e53de9STyler Retzlaff 	rte_thread_t thread_id;
8604e53de9STyler Retzlaff 	rte_cpuset_t cpuset0;
8704e53de9STyler Retzlaff 	rte_cpuset_t cpuset1;
8804e53de9STyler Retzlaff 
89*1f16100dSTyler Retzlaff 	thread_id_ready = 0;
9004e53de9STyler Retzlaff 	RTE_TEST_ASSERT(pthread_create(&id, NULL, thread_main, &thread_id) == 0,
9104e53de9STyler Retzlaff 		"Failed to create thread");
9204e53de9STyler Retzlaff 
9304e53de9STyler Retzlaff 	while (__atomic_load_n(&thread_id_ready, __ATOMIC_ACQUIRE) == 0)
9404e53de9STyler Retzlaff 		;
9504e53de9STyler Retzlaff 
9604e53de9STyler Retzlaff 	RTE_TEST_ASSERT(rte_thread_get_affinity_by_id(thread_id, &cpuset0) == 0,
9704e53de9STyler Retzlaff 		"Failed to get thread affinity");
9804e53de9STyler Retzlaff 	RTE_TEST_ASSERT(rte_thread_get_affinity_by_id(thread_id, &cpuset1) == 0,
9904e53de9STyler Retzlaff 		"Failed to get thread affinity");
10004e53de9STyler Retzlaff 	RTE_TEST_ASSERT(memcmp(&cpuset0, &cpuset1, sizeof(rte_cpuset_t)) == 0,
10104e53de9STyler Retzlaff 		"Affinity should be stable");
10204e53de9STyler Retzlaff 
10304e53de9STyler Retzlaff 	size_t i;
10404e53de9STyler Retzlaff 	for (i = 1; i < CPU_SETSIZE; i++)
10504e53de9STyler Retzlaff 		if (CPU_ISSET(i, &cpuset0)) {
10604e53de9STyler Retzlaff 			CPU_ZERO(&cpuset0);
10704e53de9STyler Retzlaff 			CPU_SET(i, &cpuset0);
10804e53de9STyler Retzlaff 
10904e53de9STyler Retzlaff 			break;
11004e53de9STyler Retzlaff 		}
11104e53de9STyler Retzlaff 	RTE_TEST_ASSERT(rte_thread_set_affinity_by_id(thread_id, &cpuset0) == 0,
11204e53de9STyler Retzlaff 		"Failed to set thread affinity");
11304e53de9STyler Retzlaff 	RTE_TEST_ASSERT(rte_thread_get_affinity_by_id(thread_id, &cpuset1) == 0,
11404e53de9STyler Retzlaff 		"Failed to get thread affinity");
11504e53de9STyler Retzlaff 	RTE_TEST_ASSERT(memcmp(&cpuset0, &cpuset1, sizeof(rte_cpuset_t)) == 0,
11604e53de9STyler Retzlaff 		"Affinity should be stable");
11704e53de9STyler Retzlaff 
11804e53de9STyler Retzlaff 	return 0;
11904e53de9STyler Retzlaff }
12004e53de9STyler Retzlaff 
12104e53de9STyler Retzlaff static struct unit_test_suite threads_test_suite = {
12204e53de9STyler Retzlaff 	.suite_name = "threads autotest",
12304e53de9STyler Retzlaff 	.setup = NULL,
12404e53de9STyler Retzlaff 	.teardown = NULL,
12504e53de9STyler Retzlaff 	.unit_test_cases = {
12604e53de9STyler Retzlaff 		TEST_CASE(test_thread_affinity),
127*1f16100dSTyler Retzlaff 		TEST_CASE(test_thread_priority),
12804e53de9STyler Retzlaff 		TEST_CASES_END()
12904e53de9STyler Retzlaff 	}
13004e53de9STyler Retzlaff };
13104e53de9STyler Retzlaff 
13204e53de9STyler Retzlaff static int
13304e53de9STyler Retzlaff test_threads(void)
13404e53de9STyler Retzlaff {
13504e53de9STyler Retzlaff 	return unit_test_suite_runner(&threads_test_suite);
13604e53de9STyler Retzlaff }
13704e53de9STyler Retzlaff 
13804e53de9STyler Retzlaff REGISTER_TEST_COMMAND(threads_autotest, test_threads);
139