xref: /dpdk/lib/eal/include/rte_thread.h (revision 09442498ef736d0a96632cf8b8c15d8ca78a6468)
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  * Set the name of the thread.
150  * This API is a noop if the underlying platform does not
151  * support setting the thread name or the platform-specific
152  * API used to set the thread name fails.
153  *
154  * @param thread_id
155  *    The id of the thread to set name.
156  *
157  * @param thread_name
158  *    The name to set. Truncated to RTE_MAX_THREAD_NAME_LEN,
159  *    including terminating NUL if necessary.
160  */
161 __rte_experimental
162 void
163 rte_thread_set_name(rte_thread_t thread_id, const char *thread_name);
164 
165 /**
166  * @warning
167  * @b EXPERIMENTAL: this API may change without prior notice.
168  *
169  * Check if 2 thread ids are equal.
170  *
171  * @param t1
172  *   First thread id.
173  *
174  * @param t2
175  *   Second thread id.
176  *
177  * @return
178  *   If the ids are equal, return nonzero.
179  *   Otherwise, return 0.
180  */
181 __rte_experimental
182 int rte_thread_equal(rte_thread_t t1, rte_thread_t t2);
183 
184 /**
185  * @warning
186  * @b EXPERIMENTAL: this API may change without prior notice.
187  *
188  * Initialize the attributes of a thread.
189  * These attributes can be passed to the rte_thread_create() function
190  * that will create a new thread and set its attributes according to attr.
191  *
192  * @param attr
193  *   Thread attributes to initialize.
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_init(rte_thread_attr_t *attr);
201 
202 /**
203  * @warning
204  * @b EXPERIMENTAL: this API may change without prior notice.
205  *
206  * Set the thread priority value in the thread attributes pointed to
207  * by 'thread_attr'.
208  *
209  * @param thread_attr
210  *   Points to the thread attributes in which priority will be updated.
211  *
212  * @param priority
213  *   Points to the value of the priority to be set.
214  *
215  * @return
216  *   On success, return 0.
217  *   On failure, return a positive errno-style error number.
218  */
219 __rte_experimental
220 int rte_thread_attr_set_priority(rte_thread_attr_t *thread_attr,
221 		enum rte_thread_priority priority);
222 
223 #ifdef RTE_HAS_CPUSET
224 
225 /**
226  * @warning
227  * @b EXPERIMENTAL: this API may change without prior notice.
228  *
229  * Set the CPU affinity value in the thread attributes pointed to
230  * by 'thread_attr'.
231  *
232  * @param thread_attr
233  *   Points to the thread attributes in which affinity will be updated.
234  *
235  * @param cpuset
236  *   Points to the value of the affinity to be set.
237  *
238  * @return
239  *   On success, return 0.
240  *   On failure, return a positive errno-style error number.
241  */
242 __rte_experimental
243 int rte_thread_attr_set_affinity(rte_thread_attr_t *thread_attr,
244 		rte_cpuset_t *cpuset);
245 
246 /**
247  * @warning
248  * @b EXPERIMENTAL: this API may change without prior notice.
249  *
250  * Get the value of CPU affinity that is set in the thread attributes pointed
251  * to by 'thread_attr'.
252  *
253  * @param thread_attr
254  *   Points to the thread attributes from which affinity will be retrieved.
255  *
256  * @param cpuset
257  *   Pointer to the memory that will store the affinity.
258  *
259  * @return
260  *   On success, return 0.
261  *   On failure, return a positive errno-style error number.
262  */
263 __rte_experimental
264 int rte_thread_attr_get_affinity(rte_thread_attr_t *thread_attr,
265 		rte_cpuset_t *cpuset);
266 
267 /**
268  * @warning
269  * @b EXPERIMENTAL: this API may change without prior notice.
270  *
271  * Set the affinity of thread 'thread_id' to the cpu set
272  * specified by 'cpuset'.
273  *
274  * @param thread_id
275  *    Id of the thread for which to set the affinity.
276  *
277  * @param cpuset
278  *   Pointer to CPU affinity to set.
279  *
280  * @return
281  *   On success, return 0.
282  *   On failure, return a positive errno-style error number.
283  */
284 __rte_experimental
285 int rte_thread_set_affinity_by_id(rte_thread_t thread_id,
286 		const rte_cpuset_t *cpuset);
287 
288 /**
289  * @warning
290  * @b EXPERIMENTAL: this API may change without prior notice.
291  *
292  * Get the affinity of thread 'thread_id' and store it
293  * in 'cpuset'.
294  *
295  * @param thread_id
296  *    Id of the thread for which to get the affinity.
297  *
298  * @param cpuset
299  *   Pointer for storing the affinity value.
300  *
301  * @return
302  *   On success, return 0.
303  *   On failure, return a positive errno-style error number.
304  */
305 __rte_experimental
306 int rte_thread_get_affinity_by_id(rte_thread_t thread_id,
307 		rte_cpuset_t *cpuset);
308 
309 /**
310  * Set core affinity of the current thread.
311  * Support both EAL and non-EAL thread and update TLS.
312  *
313  * @param cpusetp
314  *   Pointer to CPU affinity to set.
315  * @return
316  *   On success, return 0; otherwise return -1;
317  */
318 int rte_thread_set_affinity(rte_cpuset_t *cpusetp);
319 
320 /**
321  * Get core affinity of the current thread.
322  *
323  * @param cpusetp
324  *   Pointer to CPU affinity of current thread.
325  *   It presumes input is not NULL, otherwise it causes panic.
326  *
327  */
328 void rte_thread_get_affinity(rte_cpuset_t *cpusetp);
329 
330 #endif /* RTE_HAS_CPUSET */
331 
332 /**
333  * @warning
334  * @b EXPERIMENTAL: this API may change without prior notice.
335  *
336  * Get the priority of a thread.
337  *
338  * @param thread_id
339  *   Id of the thread for which to get priority.
340  *
341  * @param priority
342  *   Location to store the retrieved priority.
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_get_priority(rte_thread_t thread_id,
350 		enum rte_thread_priority *priority);
351 
352 /**
353  * @warning
354  * @b EXPERIMENTAL: this API may change without prior notice.
355  *
356  * Set the priority of a thread.
357  *
358  * @param thread_id
359  *   Id of the thread for which to set priority.
360  *
361  * @param priority
362  *   Priority value to be set.
363  *
364  * @return
365  *   On success, return 0.
366  *   On failure, return a positive errno-style error number.
367  */
368 __rte_experimental
369 int rte_thread_set_priority(rte_thread_t thread_id,
370 		enum rte_thread_priority priority);
371 
372 /**
373  * Create a TLS data key visible to all threads in the process.
374  * the created key is later used to get/set a value.
375  * and optional destructor can be set to be called when a thread exits.
376  *
377  * @param key
378  *   Pointer to store the allocated key.
379  * @param destructor
380  *   The function to be called when the thread exits.
381  *   Ignored on Windows OS.
382  *
383  * @return
384  *   On success, zero.
385  *   On failure, a negative number and an error number is set in rte_errno.
386  *   rte_errno can be: ENOMEM  - Memory allocation error.
387  *                     ENOEXEC - Specific OS error.
388  */
389 
390 __rte_experimental
391 int rte_thread_key_create(rte_thread_key *key,
392 			void (*destructor)(void *));
393 
394 /**
395  * Delete a TLS data key visible to all threads in the process.
396  *
397  * @param key
398  *   The key allocated by rte_thread_key_create().
399  *
400  * @return
401  *   On success, zero.
402  *   On failure, a negative number and an error number is set in rte_errno.
403  *   rte_errno can be: EINVAL  - Invalid parameter passed.
404  *                     ENOEXEC - Specific OS error.
405  */
406 __rte_experimental
407 int rte_thread_key_delete(rte_thread_key key);
408 
409 /**
410  * Set value bound to the TLS key on behalf of the calling thread.
411  *
412  * @param key
413  *   The key allocated by rte_thread_key_create().
414  * @param value
415  *   The value bound to the rte_thread_key key for the calling thread.
416  *
417  * @return
418  *   On success, zero.
419  *   On failure, a negative number and an error number is set in rte_errno.
420  *   rte_errno can be: EINVAL  - Invalid parameter passed.
421  *                     ENOEXEC - Specific OS error.
422  */
423 __rte_experimental
424 int rte_thread_value_set(rte_thread_key key, const void *value);
425 
426 /**
427  * Get value bound to the TLS key on behalf of the calling thread.
428  *
429  * @param key
430  *   The key allocated by rte_thread_key_create().
431  *
432  * @return
433  *   On success, value data pointer (can also be NULL).
434  *   On failure, NULL and an error number is set in rte_errno.
435  *   rte_errno can be: EINVAL  - Invalid parameter passed.
436  *                     ENOEXEC - Specific OS error.
437  */
438 __rte_experimental
439 void *rte_thread_value_get(rte_thread_key key);
440 
441 #ifdef __cplusplus
442 }
443 #endif
444 
445 #endif /* _RTE_THREAD_H_ */
446