eal: get relative core index
[dpdk.git] / lib / librte_eal / common / include / rte_lcore.h
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 -1    /**< Any lcore. */
52
53 /**
54  * Structure storing internal configuration (per-lcore)
55  */
56 struct lcore_config {
57         unsigned detected;         /**< true if lcore was detected */
58         pthread_t thread_id;       /**< pthread identifier */
59         int pipe_master2slave[2];  /**< communication pipe with master */
60         int pipe_slave2master[2];  /**< communication pipe with master */
61         lcore_function_t * volatile f;         /**< function to call */
62         void * volatile arg;       /**< argument of function */
63         volatile int ret;          /**< return value of function */
64         volatile enum rte_lcore_state_t state; /**< lcore state */
65         unsigned socket_id;        /**< physical socket id for this lcore */
66         unsigned core_id;          /**< core number on socket for this lcore */
67         int core_index;            /**< relative index, starting from 0 */
68 };
69
70 /**
71  * Internal configuration (per-lcore)
72  */
73 extern struct lcore_config lcore_config[RTE_MAX_LCORE];
74
75 RTE_DECLARE_PER_LCORE(unsigned, _lcore_id); /**< Per core "core id". */
76
77 /**
78  * Return the ID of the execution unit we are running on.
79  * @return
80  *  Logical core ID
81  */
82 static inline unsigned
83 rte_lcore_id(void)
84 {
85         return RTE_PER_LCORE(_lcore_id);
86 }
87
88 /**
89  * Get the id of the master lcore
90  *
91  * @return
92  *   the id of the master lcore
93  */
94 static inline unsigned
95 rte_get_master_lcore(void)
96 {
97         return rte_eal_get_configuration()->master_lcore;
98 }
99
100 /**
101  * Return the number of execution units (lcores) on the system.
102  *
103  * @return
104  *   the number of execution units (lcores) on the system.
105  */
106 static inline unsigned
107 rte_lcore_count(void)
108 {
109         const struct rte_config *cfg = rte_eal_get_configuration();
110         return cfg->lcore_count;
111 }
112
113 /**
114  * Return the index of the lcore starting from zero.
115  * The order is physical or given by command line (-l option).
116  *
117  * @param lcore_id
118  *   The targeted lcore, or -1 for the current one.
119  * @return
120  *   The relative index, or -1 if not enabled.
121  */
122 static inline int
123 rte_lcore_index(int lcore_id)
124 {
125         if (lcore_id >= RTE_MAX_LCORE)
126                 return -1;
127         if (lcore_id < 0)
128                 lcore_id = rte_lcore_id();
129         return lcore_config[lcore_id].core_index;
130 }
131
132 /**
133  * Return the ID of the physical socket of the logical core we are
134  * running on.
135  * @return
136  *   the ID of current lcoreid's physical socket
137  */
138 static inline unsigned
139 rte_socket_id(void)
140 {
141         return lcore_config[rte_lcore_id()].socket_id;
142 }
143
144 /**
145  * Get the ID of the physical socket of the specified lcore
146  *
147  * @param lcore_id
148  *   the targeted lcore, which MUST be between 0 and RTE_MAX_LCORE-1.
149  * @return
150  *   the ID of lcoreid's physical socket
151  */
152 static inline unsigned
153 rte_lcore_to_socket_id(unsigned lcore_id)
154 {
155         return lcore_config[lcore_id].socket_id;
156 }
157
158 /**
159  * Test if an lcore is enabled.
160  *
161  * @param lcore_id
162  *   The identifier of the lcore, which MUST be between 0 and
163  *   RTE_MAX_LCORE-1.
164  * @return
165  *   True if the given lcore is enabled; false otherwise.
166  */
167 static inline int
168 rte_lcore_is_enabled(unsigned lcore_id)
169 {
170         struct rte_config *cfg = rte_eal_get_configuration();
171         if (lcore_id >= RTE_MAX_LCORE)
172                 return 0;
173         return (cfg->lcore_role[lcore_id] != ROLE_OFF);
174 }
175
176 /**
177  * Get the next enabled lcore ID.
178  *
179  * @param i
180  *   The current lcore (reference).
181  * @param skip_master
182  *   If true, do not return the ID of the master lcore.
183  * @param wrap
184  *   If true, go back to 0 when RTE_MAX_LCORE is reached; otherwise,
185  *   return RTE_MAX_LCORE.
186  * @return
187  *   The next lcore_id or RTE_MAX_LCORE if not found.
188  */
189 static inline unsigned
190 rte_get_next_lcore(unsigned i, int skip_master, int wrap)
191 {
192         i++;
193         if (wrap)
194                 i %= RTE_MAX_LCORE;
195
196         while (i < RTE_MAX_LCORE) {
197                 if (!rte_lcore_is_enabled(i) ||
198                     (skip_master && (i == rte_get_master_lcore()))) {
199                         i++;
200                         if (wrap)
201                                 i %= RTE_MAX_LCORE;
202                         continue;
203                 }
204                 break;
205         }
206         return i;
207 }
208 /**
209  * Macro to browse all running lcores.
210  */
211 #define RTE_LCORE_FOREACH(i)                                            \
212         for (i = rte_get_next_lcore(-1, 0, 0);                          \
213              i<RTE_MAX_LCORE;                                           \
214              i = rte_get_next_lcore(i, 0, 0))
215
216 /**
217  * Macro to browse all running lcores except the master lcore.
218  */
219 #define RTE_LCORE_FOREACH_SLAVE(i)                                      \
220         for (i = rte_get_next_lcore(-1, 1, 0);                          \
221              i<RTE_MAX_LCORE;                                           \
222              i = rte_get_next_lcore(i, 1, 0))
223
224 #ifdef __cplusplus
225 }
226 #endif
227
228
229 #endif /* _RTE_LCORE_H_ */