xref: /dpdk/lib/eal/include/rte_thread.h (revision ce703c47de95528487058e7d053ec4e3ca3687c4)
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 /** Maximum thread name length (including '\0'). */
27 #define RTE_THREAD_NAME_SIZE 16
28 /* Old definition, aliased for compatibility. */
29 #define RTE_MAX_THREAD_NAME_LEN RTE_THREAD_NAME_SIZE
30 
31 /** Thread name prefix automatically added to all internal threads. */
32 #define RTE_THREAD_INTERNAL_PREFIX "dpdk-"
33 /** Maximum internal thread name length (including '\0'). */
34 #define RTE_THREAD_INTERNAL_NAME_SIZE 11
35 
36 /**
37  * Thread id descriptor.
38  */
39 typedef struct {
40 	uintptr_t opaque_id; /**< thread identifier */
41 } rte_thread_t;
42 
43 /**
44  * Thread function
45  *
46  * Function pointer to thread start routine.
47  *
48  * @param arg
49  *   Argument passed to rte_thread_create().
50  * @return
51  *   Thread function exit value.
52  */
53 typedef uint32_t (*rte_thread_func) (void *arg);
54 
55 /**
56  * Thread priority values.
57  */
58 enum rte_thread_priority {
59 	RTE_THREAD_PRIORITY_NORMAL            = 0,
60 	/**< normal thread priority, the default */
61 	RTE_THREAD_PRIORITY_REALTIME_CRITICAL = 1,
62 	/**< highest thread priority allowed */
63 };
64 
65 /**
66  * Representation for thread attributes.
67  */
68 typedef struct {
69 	enum rte_thread_priority priority; /**< thread priority */
70 #ifdef RTE_HAS_CPUSET
71 	rte_cpuset_t cpuset; /**< thread affinity */
72 #endif
73 } rte_thread_attr_t;
74 
75 /**
76  * TLS key type, an opaque pointer.
77  */
78 typedef struct eal_tls_key *rte_thread_key;
79 
80 /**
81  * Create a new thread that will invoke the 'thread_func' routine.
82  *
83  * @param thread_id
84  *    A pointer that will store the id of the newly created thread.
85  *
86  * @param thread_attr
87  *    Attributes that are used at the creation of the new thread.
88  *
89  * @param thread_func
90  *    The routine that the new thread will invoke when starting execution.
91  *
92  * @param arg
93  *    Argument to be passed to the 'thread_func' routine.
94  *
95  * @return
96  *   On success, return 0.
97  *   On failure, return a positive errno-style error number.
98  */
99 int rte_thread_create(rte_thread_t *thread_id,
100 		const rte_thread_attr_t *thread_attr,
101 		rte_thread_func thread_func, void *arg);
102 
103 /**
104  * Create a control thread.
105  *
106  * Creates a control thread with the given name and attributes. The
107  * affinity of the new thread is based on the CPU affinity retrieved
108  * at the time rte_eal_init() was called, the EAL threads are then
109  * excluded. If setting the name of the thread fails, the error is
110  * ignored and a debug message is logged.
111  *
112  * @param thread
113  *   Filled with the thread id of the new created thread.
114  * @param name
115  *   The name of the control thread
116  *   (max RTE_THREAD_NAME_SIZE characters including '\0').
117  * @param thread_func
118  *   Function to be executed by the new thread.
119  * @param arg
120  *   Argument passed to thread_func.
121  * @return
122  *   On success, returns 0; on error, it returns a negative value
123  *   corresponding to the error number.
124  */
125 int
126 rte_thread_create_control(rte_thread_t *thread, const char *name,
127 		rte_thread_func thread_func, void *arg);
128 
129 /**
130  * Create an internal control thread.
131  *
132  * Creates a control thread with the given name prefixed.
133  * If setting the name of the thread fails, the error is ignored and logged.
134  *
135  * The affinity of the new thread is based on the CPU affinity retrieved
136  * at the time rte_eal_init() was called, the EAL threads are then excluded.
137  *
138  * @param id
139  *   Filled with the thread ID of the new created thread.
140  * @param name
141  *   The name of the control thread.
142  *   See RTE_THREAD_INTERNAL_NAME_SIZE for maximum length.
143  *   The name of the driver or library should be first,
144  *   then followed by a hyphen and more details.
145  *   It will be prefixed with RTE_THREAD_INTERNAL_PREFIX by this function.
146  * @param func
147  *   Function to be executed by the new thread.
148  * @param arg
149  *   Argument passed to func.
150  * @return
151  *   On success, returns 0; a negative value otherwise.
152  */
153 __rte_internal
154 int
155 rte_thread_create_internal_control(rte_thread_t *id, const char *name,
156 		rte_thread_func func, void *arg);
157 
158 /**
159  * Waits for the thread identified by 'thread_id' to terminate
160  *
161  * @param thread_id
162  *    The identifier of the thread.
163  *
164  * @param value_ptr
165  *    Stores the exit status of the thread.
166  *
167  * @return
168  *   On success, return 0.
169  *   On failure, return a positive errno-style error number.
170  */
171 int rte_thread_join(rte_thread_t thread_id, uint32_t *value_ptr);
172 
173 /**
174  * Indicate that the return value of the thread is not needed and
175  * all thread resources should be release when the thread terminates.
176  *
177  * @param thread_id
178  *    The id of the thread to be detached.
179  *
180  * @return
181  *   On success, return 0.
182  *   On failure, return a positive errno-style error number.
183  */
184 int rte_thread_detach(rte_thread_t thread_id);
185 
186 /**
187  * Get the id of the calling thread.
188  *
189  * @return
190  *   Return the thread id of the calling thread.
191  */
192 rte_thread_t rte_thread_self(void);
193 
194 /**
195  * Set the name of the thread.
196  *
197  * This API is a noop if the underlying platform does not
198  * support setting the thread name or the platform-specific
199  * API used to set the thread name fails.
200  *
201  * @param thread_id
202  *    The id of the thread to set name.
203  *
204  * @param thread_name
205  *    The name to set. Truncated to RTE_THREAD_NAME_SIZE,
206  *    including terminating NUL if necessary.
207  */
208 void
209 rte_thread_set_name(rte_thread_t thread_id, const char *thread_name);
210 
211 /**
212  * Set the name of an internal thread with the common prefix.
213  *
214  * This API is a noop if the underlying platform does not support
215  * setting the thread name, or if it fails.
216  *
217  * @param id
218  *   The ID of the thread to set name.
219  *
220  * @param name
221  *   The name to set after being prefixed.
222  *   See RTE_THREAD_INTERNAL_NAME_SIZE for maximum length.
223  *   The name of the driver or library should be first,
224  *   then followed by a hyphen and more details.
225  *   It will be prefixed with RTE_THREAD_INTERNAL_PREFIX by this function.
226  */
227 __rte_internal
228 void
229 rte_thread_set_prefixed_name(rte_thread_t id, const char *name);
230 
231 /**
232  * Check if 2 thread ids are equal.
233  *
234  * @param t1
235  *   First thread id.
236  *
237  * @param t2
238  *   Second thread id.
239  *
240  * @return
241  *   If the ids are equal, return nonzero.
242  *   Otherwise, return 0.
243  */
244 int rte_thread_equal(rte_thread_t t1, rte_thread_t t2);
245 
246 /**
247  * Initialize the attributes of a thread.
248  * These attributes can be passed to the rte_thread_create() function
249  * that will create a new thread and set its attributes according to attr.
250  *
251  * @param attr
252  *   Thread attributes to initialize.
253  *
254  * @return
255  *   On success, return 0.
256  *   On failure, return a positive errno-style error number.
257  */
258 int rte_thread_attr_init(rte_thread_attr_t *attr);
259 
260 /**
261  * Set the thread priority value in the thread attributes pointed to
262  * by 'thread_attr'.
263  *
264  * @param thread_attr
265  *   Points to the thread attributes in which priority will be updated.
266  *
267  * @param priority
268  *   Points to the value of the priority to be set.
269  *
270  * @return
271  *   On success, return 0.
272  *   On failure, return a positive errno-style error number.
273  */
274 int rte_thread_attr_set_priority(rte_thread_attr_t *thread_attr,
275 		enum rte_thread_priority priority);
276 
277 #ifdef RTE_HAS_CPUSET
278 
279 /**
280  * Set the CPU affinity value in the thread attributes pointed to
281  * by 'thread_attr'.
282  *
283  * @param thread_attr
284  *   Points to the thread attributes in which affinity will be updated.
285  *
286  * @param cpuset
287  *   Points to the value of the affinity to be set.
288  *
289  * @return
290  *   On success, return 0.
291  *   On failure, return a positive errno-style error number.
292  */
293 int rte_thread_attr_set_affinity(rte_thread_attr_t *thread_attr,
294 		rte_cpuset_t *cpuset);
295 
296 /**
297  * Get the value of CPU affinity that is set in the thread attributes pointed
298  * to by 'thread_attr'.
299  *
300  * @param thread_attr
301  *   Points to the thread attributes from which affinity will be retrieved.
302  *
303  * @param cpuset
304  *   Pointer to the memory that will store the affinity.
305  *
306  * @return
307  *   On success, return 0.
308  *   On failure, return a positive errno-style error number.
309  */
310 int rte_thread_attr_get_affinity(rte_thread_attr_t *thread_attr,
311 		rte_cpuset_t *cpuset);
312 
313 /**
314  * Set the affinity of thread 'thread_id' to the cpu set
315  * specified by 'cpuset'.
316  *
317  * @param thread_id
318  *    Id of the thread for which to set the affinity.
319  *
320  * @param cpuset
321  *   Pointer to CPU affinity to set.
322  *
323  * @return
324  *   On success, return 0.
325  *   On failure, return a positive errno-style error number.
326  */
327 int rte_thread_set_affinity_by_id(rte_thread_t thread_id,
328 		const rte_cpuset_t *cpuset);
329 
330 /**
331  * Get the affinity of thread 'thread_id' and store it
332  * in 'cpuset'.
333  *
334  * @param thread_id
335  *    Id of the thread for which to get the affinity.
336  *
337  * @param cpuset
338  *   Pointer for storing the affinity value.
339  *
340  * @return
341  *   On success, return 0.
342  *   On failure, return a positive errno-style error number.
343  */
344 int rte_thread_get_affinity_by_id(rte_thread_t thread_id,
345 		rte_cpuset_t *cpuset);
346 
347 /**
348  * Set core affinity of the current thread.
349  * Support both EAL and non-EAL thread and update TLS.
350  *
351  * @param cpusetp
352  *   Pointer to CPU affinity to set.
353  * @return
354  *   On success, return 0; otherwise return -1;
355  */
356 int rte_thread_set_affinity(rte_cpuset_t *cpusetp);
357 
358 /**
359  * Get core affinity of the current thread.
360  *
361  * @param cpusetp
362  *   Pointer to CPU affinity of current thread.
363  *   It presumes input is not NULL, otherwise it causes panic.
364  */
365 void rte_thread_get_affinity(rte_cpuset_t *cpusetp);
366 
367 #endif /* RTE_HAS_CPUSET */
368 
369 /**
370  * Get the priority of a thread.
371  *
372  * @param thread_id
373  *   Id of the thread for which to get priority.
374  *
375  * @param priority
376  *   Location to store the retrieved priority.
377  *
378  * @return
379  *   On success, return 0.
380  *   On failure, return a positive errno-style error number.
381  */
382 int rte_thread_get_priority(rte_thread_t thread_id,
383 		enum rte_thread_priority *priority);
384 
385 /**
386  * Set the priority of a thread.
387  *
388  * @param thread_id
389  *   Id of the thread for which to set priority.
390  *
391  * @param priority
392  *   Priority value to be set.
393  *
394  * @return
395  *   On success, return 0.
396  *   On failure, return a positive errno-style error number.
397  */
398 int rte_thread_set_priority(rte_thread_t thread_id,
399 		enum rte_thread_priority priority);
400 
401 /**
402  * Create a TLS data key visible to all threads in the process.
403  * the created key is later used to get/set a value.
404  * and optional destructor can be set to be called when a thread exits.
405  *
406  * @param key
407  *   Pointer to store the allocated key.
408  * @param destructor
409  *   The function to be called when the thread exits.
410  *   Ignored on Windows OS.
411  *
412  * @return
413  *   On success, zero.
414  *   On failure, a negative number and an error number is set in rte_errno.
415  *   rte_errno can be: ENOMEM  - Memory allocation error.
416  *                     ENOEXEC - Specific OS error.
417  */
418 
419 int rte_thread_key_create(rte_thread_key *key,
420 			void (*destructor)(void *));
421 
422 /**
423  * Delete a TLS data key visible to all threads in the process.
424  *
425  * @param key
426  *   The key allocated by rte_thread_key_create().
427  *
428  * @return
429  *   On success, zero.
430  *   On failure, a negative number and an error number is set in rte_errno.
431  *   rte_errno can be: EINVAL  - Invalid parameter passed.
432  *                     ENOEXEC - Specific OS error.
433  */
434 int rte_thread_key_delete(rte_thread_key key);
435 
436 /**
437  * Set value bound to the TLS key on behalf of the calling thread.
438  *
439  * @param key
440  *   The key allocated by rte_thread_key_create().
441  * @param value
442  *   The value bound to the rte_thread_key key for the calling thread.
443  *
444  * @return
445  *   On success, zero.
446  *   On failure, a negative number and an error number is set in rte_errno.
447  *   rte_errno can be: EINVAL  - Invalid parameter passed.
448  *                     ENOEXEC - Specific OS error.
449  */
450 int rte_thread_value_set(rte_thread_key key, const void *value);
451 
452 /**
453  * Get value bound to the TLS key on behalf of the calling thread.
454  *
455  * @param key
456  *   The key allocated by rte_thread_key_create().
457  *
458  * @return
459  *   On success, value data pointer (can also be NULL).
460  *   On failure, NULL and an error number is set in rte_errno.
461  *   rte_errno can be: EINVAL  - Invalid parameter passed.
462  *                     ENOEXEC - Specific OS error.
463  */
464 void *rte_thread_value_get(rte_thread_key key);
465 
466 #ifdef __cplusplus
467 }
468 #endif
469 
470 #endif /* _RTE_THREAD_H_ */
471