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