xref: /dpdk/lib/eal/include/rte_thread.h (revision f9dfb59edbccae50e7c5508348aa2b4b84413048)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2021 Mellanox Technologies, Ltd
3  * Copyright (C) 2022 Microsoft Corporation
4  */
5 
6 #include <stdint.h>
7 
8 #include <rte_os.h>
9 #include <rte_compat.h>
10 
11 #ifndef _RTE_THREAD_H_
12 #define _RTE_THREAD_H_
13 
14 /**
15  * @file
16  *
17  * Threading functions
18  *
19  * Simple threads functionality supplied by EAL.
20  */
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 /**
27  * Thread id descriptor.
28  */
29 typedef struct {
30 	uintptr_t opaque_id; /**< thread identifier */
31 } rte_thread_t;
32 
33 /**
34  * Thread function
35  *
36  * Function pointer to thread start routine.
37  *
38  * @param arg
39  *   Argument passed to rte_thread_create().
40  * @return
41  *   Thread function exit value.
42  */
43 typedef uint32_t (*rte_thread_func) (void *arg);
44 
45 /**
46  * Thread priority values.
47  */
48 enum rte_thread_priority {
49 	RTE_THREAD_PRIORITY_NORMAL            = 0,
50 	/**< normal thread priority, the default */
51 	RTE_THREAD_PRIORITY_REALTIME_CRITICAL = 1,
52 	/**< highest thread priority allowed */
53 };
54 
55 /**
56  * Representation for thread attributes.
57  */
58 typedef struct {
59 	enum rte_thread_priority priority; /**< thread priority */
60 #ifdef RTE_HAS_CPUSET
61 	rte_cpuset_t cpuset; /**< thread affinity */
62 #endif
63 } rte_thread_attr_t;
64 
65 /**
66  * TLS key type, an opaque pointer.
67  */
68 typedef struct eal_tls_key *rte_thread_key;
69 
70 /**
71  * @warning
72  * @b EXPERIMENTAL: this API may change without prior notice.
73  *
74  * Create a new thread that will invoke the 'thread_func' routine.
75  *
76  * @param thread_id
77  *    A pointer that will store the id of the newly created thread.
78  *
79  * @param thread_attr
80  *    Attributes that are used at the creation of the new thread.
81  *
82  * @param thread_func
83  *    The routine that the new thread will invoke when starting execution.
84  *
85  * @param arg
86  *    Argument to be passed to the 'thread_func' routine.
87  *
88  * @return
89  *   On success, return 0.
90  *   On failure, return a positive errno-style error number.
91  */
92 __rte_experimental
93 int rte_thread_create(rte_thread_t *thread_id,
94 		const rte_thread_attr_t *thread_attr,
95 		rte_thread_func thread_func, void *arg);
96 
97 /**
98  * @warning
99  * @b EXPERIMENTAL: this API may change without prior notice.
100  *
101  * Waits for the thread identified by 'thread_id' to terminate
102  *
103  * @param thread_id
104  *    The identifier of the thread.
105  *
106  * @param value_ptr
107  *    Stores the exit status of the thread.
108  *
109  * @return
110  *   On success, return 0.
111  *   On failure, return a positive errno-style error number.
112  */
113 __rte_experimental
114 int rte_thread_join(rte_thread_t thread_id, uint32_t *value_ptr);
115 
116 /**
117  * @warning
118  * @b EXPERIMENTAL: this API may change without prior notice.
119  *
120  * Indicate that the return value of the thread is not needed and
121  * all thread resources should be release when the thread terminates.
122  *
123  * @param thread_id
124  *    The id of the thread to be detached.
125  *
126  * @return
127  *   On success, return 0.
128  *   On failure, return a positive errno-style error number.
129  */
130 __rte_experimental
131 int rte_thread_detach(rte_thread_t thread_id);
132 
133 /**
134  * @warning
135  * @b EXPERIMENTAL: this API may change without prior notice.
136  *
137  * Get the id of the calling thread.
138  *
139  * @return
140  *   Return the thread id of the calling thread.
141  */
142 __rte_experimental
143 rte_thread_t rte_thread_self(void);
144 
145 /**
146  * @warning
147  * @b EXPERIMENTAL: this API may change without prior notice.
148  *
149  * Check if 2 thread ids are equal.
150  *
151  * @param t1
152  *   First thread id.
153  *
154  * @param t2
155  *   Second thread id.
156  *
157  * @return
158  *   If the ids are equal, return nonzero.
159  *   Otherwise, return 0.
160  */
161 __rte_experimental
162 int rte_thread_equal(rte_thread_t t1, rte_thread_t t2);
163 
164 /**
165  * @warning
166  * @b EXPERIMENTAL: this API may change without prior notice.
167  *
168  * Initialize the attributes of a thread.
169  * These attributes can be passed to the rte_thread_create() function
170  * that will create a new thread and set its attributes according to attr.
171  *
172  * @param attr
173  *   Thread attributes to initialize.
174  *
175  * @return
176  *   On success, return 0.
177  *   On failure, return a positive errno-style error number.
178  */
179 __rte_experimental
180 int rte_thread_attr_init(rte_thread_attr_t *attr);
181 
182 /**
183  * @warning
184  * @b EXPERIMENTAL: this API may change without prior notice.
185  *
186  * Set the thread priority value in the thread attributes pointed to
187  * by 'thread_attr'.
188  *
189  * @param thread_attr
190  *   Points to the thread attributes in which priority will be updated.
191  *
192  * @param priority
193  *   Points to the value of the priority to be set.
194  *
195  * @return
196  *   On success, return 0.
197  *   On failure, return a positive errno-style error number.
198  */
199 __rte_experimental
200 int rte_thread_attr_set_priority(rte_thread_attr_t *thread_attr,
201 		enum rte_thread_priority priority);
202 
203 #ifdef RTE_HAS_CPUSET
204 
205 /**
206  * @warning
207  * @b EXPERIMENTAL: this API may change without prior notice.
208  *
209  * Set the CPU affinity value in the thread attributes pointed to
210  * by 'thread_attr'.
211  *
212  * @param thread_attr
213  *   Points to the thread attributes in which affinity will be updated.
214  *
215  * @param cpuset
216  *   Points to the value of the affinity to be set.
217  *
218  * @return
219  *   On success, return 0.
220  *   On failure, return a positive errno-style error number.
221  */
222 __rte_experimental
223 int rte_thread_attr_set_affinity(rte_thread_attr_t *thread_attr,
224 		rte_cpuset_t *cpuset);
225 
226 /**
227  * @warning
228  * @b EXPERIMENTAL: this API may change without prior notice.
229  *
230  * Get the value of CPU affinity that is set in the thread attributes pointed
231  * to by 'thread_attr'.
232  *
233  * @param thread_attr
234  *   Points to the thread attributes from which affinity will be retrieved.
235  *
236  * @param cpuset
237  *   Pointer to the memory that will store the affinity.
238  *
239  * @return
240  *   On success, return 0.
241  *   On failure, return a positive errno-style error number.
242  */
243 __rte_experimental
244 int rte_thread_attr_get_affinity(rte_thread_attr_t *thread_attr,
245 		rte_cpuset_t *cpuset);
246 
247 /**
248  * @warning
249  * @b EXPERIMENTAL: this API may change without prior notice.
250  *
251  * Set the affinity of thread 'thread_id' to the cpu set
252  * specified by 'cpuset'.
253  *
254  * @param thread_id
255  *    Id of the thread for which to set the affinity.
256  *
257  * @param cpuset
258  *   Pointer to CPU affinity to set.
259  *
260  * @return
261  *   On success, return 0.
262  *   On failure, return a positive errno-style error number.
263  */
264 __rte_experimental
265 int rte_thread_set_affinity_by_id(rte_thread_t thread_id,
266 		const rte_cpuset_t *cpuset);
267 
268 /**
269  * @warning
270  * @b EXPERIMENTAL: this API may change without prior notice.
271  *
272  * Get the affinity of thread 'thread_id' and store it
273  * in 'cpuset'.
274  *
275  * @param thread_id
276  *    Id of the thread for which to get the affinity.
277  *
278  * @param cpuset
279  *   Pointer for storing the affinity value.
280  *
281  * @return
282  *   On success, return 0.
283  *   On failure, return a positive errno-style error number.
284  */
285 __rte_experimental
286 int rte_thread_get_affinity_by_id(rte_thread_t thread_id,
287 		rte_cpuset_t *cpuset);
288 
289 /**
290  * Set core affinity of the current thread.
291  * Support both EAL and non-EAL thread and update TLS.
292  *
293  * @param cpusetp
294  *   Pointer to CPU affinity to set.
295  * @return
296  *   On success, return 0; otherwise return -1;
297  */
298 int rte_thread_set_affinity(rte_cpuset_t *cpusetp);
299 
300 /**
301  * Get core affinity of the current thread.
302  *
303  * @param cpusetp
304  *   Pointer to CPU affinity of current thread.
305  *   It presumes input is not NULL, otherwise it causes panic.
306  *
307  */
308 void rte_thread_get_affinity(rte_cpuset_t *cpusetp);
309 
310 #endif /* RTE_HAS_CPUSET */
311 
312 /**
313  * @warning
314  * @b EXPERIMENTAL: this API may change without prior notice.
315  *
316  * Get the priority of a thread.
317  *
318  * @param thread_id
319  *   Id of the thread for which to get priority.
320  *
321  * @param priority
322  *   Location to store the retrieved priority.
323  *
324  * @return
325  *   On success, return 0.
326  *   On failure, return a positive errno-style error number.
327  */
328 __rte_experimental
329 int rte_thread_get_priority(rte_thread_t thread_id,
330 		enum rte_thread_priority *priority);
331 
332 /**
333  * @warning
334  * @b EXPERIMENTAL: this API may change without prior notice.
335  *
336  * Set the priority of a thread.
337  *
338  * @param thread_id
339  *   Id of the thread for which to set priority.
340  *
341  * @param priority
342  *   Priority value to be set.
343  *
344  * @return
345  *   On success, return 0.
346  *   On failure, return a positive errno-style error number.
347  */
348 __rte_experimental
349 int rte_thread_set_priority(rte_thread_t thread_id,
350 		enum rte_thread_priority priority);
351 
352 /**
353  * Create a TLS data key visible to all threads in the process.
354  * the created key is later used to get/set a value.
355  * and optional destructor can be set to be called when a thread exits.
356  *
357  * @param key
358  *   Pointer to store the allocated key.
359  * @param destructor
360  *   The function to be called when the thread exits.
361  *   Ignored on Windows OS.
362  *
363  * @return
364  *   On success, zero.
365  *   On failure, a negative number and an error number is set in rte_errno.
366  *   rte_errno can be: ENOMEM  - Memory allocation error.
367  *                     ENOEXEC - Specific OS error.
368  */
369 
370 __rte_experimental
371 int rte_thread_key_create(rte_thread_key *key,
372 			void (*destructor)(void *));
373 
374 /**
375  * Delete a TLS data key visible to all threads in the process.
376  *
377  * @param key
378  *   The key allocated by rte_thread_key_create().
379  *
380  * @return
381  *   On success, zero.
382  *   On failure, a negative number and an error number is set in rte_errno.
383  *   rte_errno can be: EINVAL  - Invalid parameter passed.
384  *                     ENOEXEC - Specific OS error.
385  */
386 __rte_experimental
387 int rte_thread_key_delete(rte_thread_key key);
388 
389 /**
390  * Set value bound to the TLS key on behalf of the calling thread.
391  *
392  * @param key
393  *   The key allocated by rte_thread_key_create().
394  * @param value
395  *   The value bound to the rte_thread_key key for the calling thread.
396  *
397  * @return
398  *   On success, zero.
399  *   On failure, a negative number and an error number is set in rte_errno.
400  *   rte_errno can be: EINVAL  - Invalid parameter passed.
401  *                     ENOEXEC - Specific OS error.
402  */
403 __rte_experimental
404 int rte_thread_value_set(rte_thread_key key, const void *value);
405 
406 /**
407  * Get value bound to the TLS key on behalf of the calling thread.
408  *
409  * @param key
410  *   The key allocated by rte_thread_key_create().
411  *
412  * @return
413  *   On success, value data pointer (can also be NULL).
414  *   On failure, NULL and an error number is set in rte_errno.
415  *   rte_errno can be: EINVAL  - Invalid parameter passed.
416  *                     ENOEXEC - Specific OS error.
417  */
418 __rte_experimental
419 void *rte_thread_value_get(rte_thread_key key);
420 
421 #ifdef __cplusplus
422 }
423 #endif
424 
425 #endif /* _RTE_THREAD_H_ */
426