]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*- |
2 | * BSD LICENSE | |
3 | * | |
4 | * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. | |
5 | * All rights reserved. | |
6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | |
10 | * | |
11 | * * Redistributions of source code must retain the above copyright | |
12 | * notice, this list of conditions and the following disclaimer. | |
13 | * * Redistributions in binary form must reproduce the above copyright | |
14 | * notice, this list of conditions and the following disclaimer in | |
15 | * the documentation and/or other materials provided with the | |
16 | * distribution. | |
17 | * * Neither the name of Intel Corporation nor the names of its | |
18 | * contributors may be used to endorse or promote products derived | |
19 | * from this software without specific prior written permission. | |
20 | * | |
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
24 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
25 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
27 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
32 | */ | |
33 | ||
34 | #ifndef _RTE_LCORE_H_ | |
35 | #define _RTE_LCORE_H_ | |
36 | ||
37 | /** | |
38 | * @file | |
39 | * | |
40 | * API for lcore and socket manipulation | |
41 | * | |
42 | */ | |
43 | #include <rte_per_lcore.h> | |
44 | #include <rte_eal.h> | |
45 | #include <rte_launch.h> | |
46 | ||
47 | #ifdef __cplusplus | |
48 | extern "C" { | |
49 | #endif | |
50 | ||
51 | #define LCORE_ID_ANY UINT32_MAX /**< Any lcore. */ | |
52 | ||
53 | #if defined(__linux__) | |
54 | typedef cpu_set_t rte_cpuset_t; | |
55 | #elif defined(__FreeBSD__) | |
56 | #include <pthread_np.h> | |
57 | typedef cpuset_t rte_cpuset_t; | |
58 | #endif | |
59 | ||
60 | /** | |
61 | * Structure storing internal configuration (per-lcore) | |
62 | */ | |
63 | struct lcore_config { | |
64 | unsigned detected; /**< true if lcore was detected */ | |
65 | pthread_t thread_id; /**< pthread identifier */ | |
66 | int pipe_master2slave[2]; /**< communication pipe with master */ | |
67 | int pipe_slave2master[2]; /**< communication pipe with master */ | |
68 | lcore_function_t * volatile f; /**< function to call */ | |
69 | void * volatile arg; /**< argument of function */ | |
70 | volatile int ret; /**< return value of function */ | |
71 | volatile enum rte_lcore_state_t state; /**< lcore state */ | |
72 | unsigned socket_id; /**< physical socket id for this lcore */ | |
73 | unsigned core_id; /**< core number on socket for this lcore */ | |
74 | int core_index; /**< relative index, starting from 0 */ | |
75 | rte_cpuset_t cpuset; /**< cpu set which the lcore affinity to */ | |
76 | }; | |
77 | ||
78 | /** | |
79 | * Internal configuration (per-lcore) | |
80 | */ | |
81 | extern struct lcore_config lcore_config[RTE_MAX_LCORE]; | |
82 | ||
83 | RTE_DECLARE_PER_LCORE(unsigned, _lcore_id); /**< Per thread "lcore id". */ | |
84 | RTE_DECLARE_PER_LCORE(rte_cpuset_t, _cpuset); /**< Per thread "cpuset". */ | |
85 | ||
86 | /** | |
87 | * Return the ID of the execution unit we are running on. | |
88 | * @return | |
89 | * Logical core ID (in EAL thread) or LCORE_ID_ANY (in non-EAL thread) | |
90 | */ | |
91 | static inline unsigned | |
92 | rte_lcore_id(void) | |
93 | { | |
94 | return RTE_PER_LCORE(_lcore_id); | |
95 | } | |
96 | ||
97 | /** | |
98 | * Get the id of the master lcore | |
99 | * | |
100 | * @return | |
101 | * the id of the master lcore | |
102 | */ | |
103 | static inline unsigned | |
104 | rte_get_master_lcore(void) | |
105 | { | |
106 | return rte_eal_get_configuration()->master_lcore; | |
107 | } | |
108 | ||
109 | /** | |
110 | * Return the number of execution units (lcores) on the system. | |
111 | * | |
112 | * @return | |
113 | * the number of execution units (lcores) on the system. | |
114 | */ | |
115 | static inline unsigned | |
116 | rte_lcore_count(void) | |
117 | { | |
118 | const struct rte_config *cfg = rte_eal_get_configuration(); | |
119 | return cfg->lcore_count; | |
120 | } | |
121 | ||
122 | /** | |
123 | * Return the index of the lcore starting from zero. | |
124 | * The order is physical or given by command line (-l option). | |
125 | * | |
126 | * @param lcore_id | |
127 | * The targeted lcore, or -1 for the current one. | |
128 | * @return | |
129 | * The relative index, or -1 if not enabled. | |
130 | */ | |
131 | static inline int | |
132 | rte_lcore_index(int lcore_id) | |
133 | { | |
134 | if (lcore_id >= RTE_MAX_LCORE) | |
135 | return -1; | |
136 | if (lcore_id < 0) | |
137 | lcore_id = rte_lcore_id(); | |
138 | return lcore_config[lcore_id].core_index; | |
139 | } | |
140 | ||
141 | /** | |
142 | * Return the ID of the physical socket of the logical core we are | |
143 | * running on. | |
144 | * @return | |
145 | * the ID of current lcoreid's physical socket | |
146 | */ | |
147 | unsigned rte_socket_id(void); | |
148 | ||
149 | /** | |
150 | * Get the ID of the physical socket of the specified lcore | |
151 | * | |
152 | * @param lcore_id | |
153 | * the targeted lcore, which MUST be between 0 and RTE_MAX_LCORE-1. | |
154 | * @return | |
155 | * the ID of lcoreid's physical socket | |
156 | */ | |
157 | static inline unsigned | |
158 | rte_lcore_to_socket_id(unsigned lcore_id) | |
159 | { | |
160 | return lcore_config[lcore_id].socket_id; | |
161 | } | |
162 | ||
163 | /** | |
164 | * Test if an lcore is enabled. | |
165 | * | |
166 | * @param lcore_id | |
167 | * The identifier of the lcore, which MUST be between 0 and | |
168 | * RTE_MAX_LCORE-1. | |
169 | * @return | |
170 | * True if the given lcore is enabled; false otherwise. | |
171 | */ | |
172 | static inline int | |
173 | rte_lcore_is_enabled(unsigned lcore_id) | |
174 | { | |
175 | struct rte_config *cfg = rte_eal_get_configuration(); | |
176 | if (lcore_id >= RTE_MAX_LCORE) | |
177 | return 0; | |
178 | return cfg->lcore_role[lcore_id] != ROLE_OFF; | |
179 | } | |
180 | ||
181 | /** | |
182 | * Get the next enabled lcore ID. | |
183 | * | |
184 | * @param i | |
185 | * The current lcore (reference). | |
186 | * @param skip_master | |
187 | * If true, do not return the ID of the master lcore. | |
188 | * @param wrap | |
189 | * If true, go back to 0 when RTE_MAX_LCORE is reached; otherwise, | |
190 | * return RTE_MAX_LCORE. | |
191 | * @return | |
192 | * The next lcore_id or RTE_MAX_LCORE if not found. | |
193 | */ | |
194 | static inline unsigned | |
195 | rte_get_next_lcore(unsigned i, int skip_master, int wrap) | |
196 | { | |
197 | i++; | |
198 | if (wrap) | |
199 | i %= RTE_MAX_LCORE; | |
200 | ||
201 | while (i < RTE_MAX_LCORE) { | |
202 | if (!rte_lcore_is_enabled(i) || | |
203 | (skip_master && (i == rte_get_master_lcore()))) { | |
204 | i++; | |
205 | if (wrap) | |
206 | i %= RTE_MAX_LCORE; | |
207 | continue; | |
208 | } | |
209 | break; | |
210 | } | |
211 | return i; | |
212 | } | |
213 | /** | |
214 | * Macro to browse all running lcores. | |
215 | */ | |
216 | #define RTE_LCORE_FOREACH(i) \ | |
217 | for (i = rte_get_next_lcore(-1, 0, 0); \ | |
218 | i<RTE_MAX_LCORE; \ | |
219 | i = rte_get_next_lcore(i, 0, 0)) | |
220 | ||
221 | /** | |
222 | * Macro to browse all running lcores except the master lcore. | |
223 | */ | |
224 | #define RTE_LCORE_FOREACH_SLAVE(i) \ | |
225 | for (i = rte_get_next_lcore(-1, 1, 0); \ | |
226 | i<RTE_MAX_LCORE; \ | |
227 | i = rte_get_next_lcore(i, 1, 0)) | |
228 | ||
229 | /** | |
230 | * Set core affinity of the current thread. | |
231 | * Support both EAL and non-EAL thread and update TLS. | |
232 | * | |
233 | * @param cpusetp | |
234 | * Point to cpu_set_t for setting current thread affinity. | |
235 | * @return | |
236 | * On success, return 0; otherwise return -1; | |
237 | */ | |
238 | int rte_thread_set_affinity(rte_cpuset_t *cpusetp); | |
239 | ||
240 | /** | |
241 | * Get core affinity of the current thread. | |
242 | * | |
243 | * @param cpusetp | |
244 | * Point to cpu_set_t for getting current thread cpu affinity. | |
245 | * It presumes input is not NULL, otherwise it causes panic. | |
246 | * | |
247 | */ | |
248 | void rte_thread_get_affinity(rte_cpuset_t *cpusetp); | |
249 | ||
250 | /** | |
251 | * Set thread names. | |
252 | * | |
253 | * @note It fails with glibc < 2.12. | |
254 | * | |
255 | * @param id | |
256 | * Thread id. | |
257 | * @param name | |
258 | * Thread name to set. | |
259 | * @return | |
260 | * On success, return 0; otherwise return a negative value. | |
261 | */ | |
262 | int rte_thread_setname(pthread_t id, const char *name); | |
263 | ||
264 | #ifdef __cplusplus | |
265 | } | |
266 | #endif | |
267 | ||
268 | ||
269 | #endif /* _RTE_LCORE_H_ */ |