1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2014 Intel Corporation
15 #include <rte_lcore.h>
16 #include <rte_memory.h>
19 #include "eal_private.h"
20 #include "eal_thread.h"
22 RTE_DECLARE_PER_LCORE(unsigned , _socket_id
);
24 unsigned rte_socket_id(void)
26 return RTE_PER_LCORE(_socket_id
);
30 rte_lcore_has_role(unsigned int lcore_id
, enum rte_lcore_role_t role
)
32 struct rte_config
*cfg
= rte_eal_get_configuration();
34 if (lcore_id
>= RTE_MAX_LCORE
)
37 return cfg
->lcore_role
[lcore_id
] == role
;
40 int eal_cpuset_socket_id(rte_cpuset_t
*cpusetp
)
43 int socket_id
= SOCKET_ID_ANY
;
50 if (!CPU_ISSET(cpu
, cpusetp
))
53 if (socket_id
== SOCKET_ID_ANY
)
54 socket_id
= eal_cpu_socket_id(cpu
);
56 sid
= eal_cpu_socket_id(cpu
);
57 if (socket_id
!= sid
) {
58 socket_id
= SOCKET_ID_ANY
;
62 } while (++cpu
< RTE_MAX_LCORE
);
68 rte_thread_set_affinity(rte_cpuset_t
*cpusetp
)
76 s
= pthread_setaffinity_np(tid
, sizeof(rte_cpuset_t
), cpusetp
);
78 RTE_LOG(ERR
, EAL
, "pthread_setaffinity_np failed\n");
82 /* store socket_id in TLS for quick access */
83 RTE_PER_LCORE(_socket_id
) =
84 eal_cpuset_socket_id(cpusetp
);
86 /* store cpuset in TLS for quick access */
87 memmove(&RTE_PER_LCORE(_cpuset
), cpusetp
,
88 sizeof(rte_cpuset_t
));
90 lcore_id
= rte_lcore_id();
91 if (lcore_id
!= (unsigned)LCORE_ID_ANY
) {
92 /* EAL thread will update lcore_config */
93 lcore_config
[lcore_id
].socket_id
= RTE_PER_LCORE(_socket_id
);
94 memmove(&lcore_config
[lcore_id
].cpuset
, cpusetp
,
95 sizeof(rte_cpuset_t
));
102 rte_thread_get_affinity(rte_cpuset_t
*cpusetp
)
105 memmove(cpusetp
, &RTE_PER_LCORE(_cpuset
),
106 sizeof(rte_cpuset_t
));
110 eal_thread_dump_affinity(char *str
, unsigned size
)
115 unsigned int out
= 0;
117 rte_thread_get_affinity(&cpuset
);
119 for (cpu
= 0; cpu
< RTE_MAX_LCORE
; cpu
++) {
120 if (!CPU_ISSET(cpu
, &cpuset
))
123 ret
= snprintf(str
+ out
,
124 size
- out
, "%u,", cpu
);
125 if (ret
< 0 || (unsigned)ret
>= size
- out
) {
126 /* string will be truncated */
136 /* remove the last separator */
144 struct rte_thread_ctrl_params
{
145 void *(*start_routine
)(void *);
147 pthread_barrier_t configured
;
150 static void *rte_thread_init(void *arg
)
153 struct rte_thread_ctrl_params
*params
= arg
;
154 void *(*start_routine
)(void *) = params
->start_routine
;
155 void *routine_arg
= params
->arg
;
157 ret
= pthread_barrier_wait(¶ms
->configured
);
158 if (ret
== PTHREAD_BARRIER_SERIAL_THREAD
) {
159 pthread_barrier_destroy(¶ms
->configured
);
163 return start_routine(routine_arg
);
166 __rte_experimental
int
167 rte_ctrl_thread_create(pthread_t
*thread
, const char *name
,
168 const pthread_attr_t
*attr
,
169 void *(*start_routine
)(void *), void *arg
)
171 struct rte_thread_ctrl_params
*params
;
172 unsigned int lcore_id
;
176 params
= malloc(sizeof(*params
));
180 params
->start_routine
= start_routine
;
183 pthread_barrier_init(¶ms
->configured
, NULL
, 2);
185 ret
= pthread_create(thread
, attr
, rte_thread_init
, (void *)params
);
192 ret
= rte_thread_setname(*thread
, name
);
195 "Cannot set name for ctrl thread\n");
200 for (lcore_id
= 0; lcore_id
< RTE_MAX_LCORE
; lcore_id
++) {
201 if (eal_cpu_detected(lcore_id
) &&
202 rte_lcore_has_role(lcore_id
, ROLE_OFF
)) {
203 CPU_SET(lcore_id
, &cpuset
);
207 /* if no detected cpu is off, use master core */
209 CPU_SET(rte_get_master_lcore(), &cpuset
);
211 ret
= pthread_setaffinity_np(*thread
, sizeof(cpuset
), &cpuset
);
215 ret
= pthread_barrier_wait(¶ms
->configured
);
216 if (ret
== PTHREAD_BARRIER_SERIAL_THREAD
) {
217 pthread_barrier_destroy(¶ms
->configured
);
224 if (PTHREAD_BARRIER_SERIAL_THREAD
==
225 pthread_barrier_wait(¶ms
->configured
)) {
226 pthread_barrier_destroy(¶ms
->configured
);
229 pthread_cancel(*thread
);
230 pthread_join(*thread
, NULL
);