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