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