1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (c) 2020 Red Hat, Inc.
13 struct thread_context {
14 enum { INIT, ERROR, DONE } state;
17 unsigned int *registered_count;
20 static void *thread_loop(void *arg)
22 struct thread_context *t = arg;
23 unsigned int lcore_id;
25 lcore_id = rte_lcore_id();
26 if (lcore_id != LCORE_ID_ANY) {
27 printf("Error: incorrect lcore id for new thread %u\n", lcore_id);
30 if (rte_thread_register() < 0)
31 printf("Warning: could not register new thread (this might be expected during this test), reason %s\n",
32 rte_strerror(rte_errno));
33 lcore_id = rte_lcore_id();
34 if ((t->lcore_id_any && lcore_id != LCORE_ID_ANY) ||
35 (!t->lcore_id_any && lcore_id == LCORE_ID_ANY)) {
36 printf("Error: could not register new thread, got %u while %sexpecting %u\n",
37 lcore_id, t->lcore_id_any ? "" : "not ", LCORE_ID_ANY);
40 /* Report register happened to the control thread. */
41 __atomic_add_fetch(t->registered_count, 1, __ATOMIC_RELEASE);
43 /* Wait for release from the control thread. */
44 while (__atomic_load_n(t->registered_count, __ATOMIC_ACQUIRE) != 0)
46 rte_thread_unregister();
47 lcore_id = rte_lcore_id();
48 if (lcore_id != LCORE_ID_ANY) {
49 printf("Error: could not unregister new thread, %u still assigned\n",
54 if (t->state != ERROR)
61 test_non_eal_lcores(unsigned int eal_threads_count)
63 struct thread_context thread_contexts[RTE_MAX_LCORE];
64 unsigned int non_eal_threads_count;
65 unsigned int registered_count;
66 struct thread_context *t;
70 non_eal_threads_count = 0;
73 /* Try to create as many threads as possible. */
74 for (i = 0; i < RTE_MAX_LCORE - eal_threads_count; i++) {
75 t = &thread_contexts[i];
77 t->registered_count = ®istered_count;
78 t->lcore_id_any = false;
79 if (pthread_create(&t->id, NULL, thread_loop, t) != 0)
81 non_eal_threads_count++;
83 printf("non-EAL threads count: %u\n", non_eal_threads_count);
84 /* Wait all non-EAL threads to register. */
85 while (__atomic_load_n(®istered_count, __ATOMIC_ACQUIRE) !=
86 non_eal_threads_count)
89 /* We managed to create the max number of threads, let's try to create
90 * one more. This will allow one more check.
92 if (eal_threads_count + non_eal_threads_count < RTE_MAX_LCORE)
94 t = &thread_contexts[non_eal_threads_count];
96 t->registered_count = ®istered_count;
97 t->lcore_id_any = true;
98 if (pthread_create(&t->id, NULL, thread_loop, t) == 0) {
99 non_eal_threads_count++;
100 printf("non-EAL threads count: %u\n", non_eal_threads_count);
101 while (__atomic_load_n(®istered_count, __ATOMIC_ACQUIRE) !=
102 non_eal_threads_count)
107 /* Release all threads, and check their states. */
108 __atomic_store_n(®istered_count, 0, __ATOMIC_RELEASE);
110 for (i = 0; i < non_eal_threads_count; i++) {
111 t = &thread_contexts[i];
112 pthread_join(t->id, NULL);
113 if (t->state != DONE)
123 unsigned int eal_threads_count = 0;
126 for (i = 0; i < RTE_MAX_LCORE; i++) {
127 if (!rte_lcore_has_role(i, ROLE_OFF))
130 if (eal_threads_count == 0) {
131 printf("Error: something is broken, no EAL thread detected.\n");
134 printf("EAL threads count: %u, RTE_MAX_LCORE=%u\n", eal_threads_count,
137 if (test_non_eal_lcores(eal_threads_count) < 0)
143 REGISTER_TEST_COMMAND(lcores_autotest, test_lcores);