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 * Create a control thread. 102 * 103 * Creates a control thread with the given name and attributes. The 104 * affinity of the new thread is based on the CPU affinity retrieved 105 * at the time rte_eal_init() was called, the EAL threads are then 106 * excluded. If setting the name of the thread fails, the error is 107 * ignored and a debug message is logged. 108 * 109 * @param thread 110 * Filled with the thread id of the new created thread. 111 * @param name 112 * The name of the control thread 113 * (max RTE_MAX_THREAD_NAME_LEN characters including '\0'). 114 * @param thread_attr 115 * Attributes for the new thread. 116 * @param thread_func 117 * Function to be executed by the new thread. 118 * @param arg 119 * Argument passed to start_routine. 120 * @return 121 * On success, returns 0; on error, it returns a negative value 122 * corresponding to the error number. 123 */ 124 __rte_experimental 125 int 126 rte_thread_create_control(rte_thread_t *thread, const char *name, 127 const rte_thread_attr_t *thread_attr, rte_thread_func thread_func, 128 void *arg); 129 130 /** 131 * @warning 132 * @b EXPERIMENTAL: this API may change without prior notice. 133 * 134 * Waits for the thread identified by 'thread_id' to terminate 135 * 136 * @param thread_id 137 * The identifier of the thread. 138 * 139 * @param value_ptr 140 * Stores the exit status of the thread. 141 * 142 * @return 143 * On success, return 0. 144 * On failure, return a positive errno-style error number. 145 */ 146 __rte_experimental 147 int rte_thread_join(rte_thread_t thread_id, uint32_t *value_ptr); 148 149 /** 150 * @warning 151 * @b EXPERIMENTAL: this API may change without prior notice. 152 * 153 * Indicate that the return value of the thread is not needed and 154 * all thread resources should be release when the thread terminates. 155 * 156 * @param thread_id 157 * The id of the thread to be detached. 158 * 159 * @return 160 * On success, return 0. 161 * On failure, return a positive errno-style error number. 162 */ 163 __rte_experimental 164 int rte_thread_detach(rte_thread_t thread_id); 165 166 /** 167 * @warning 168 * @b EXPERIMENTAL: this API may change without prior notice. 169 * 170 * Get the id of the calling thread. 171 * 172 * @return 173 * Return the thread id of the calling thread. 174 */ 175 __rte_experimental 176 rte_thread_t rte_thread_self(void); 177 178 /** 179 * @warning 180 * @b EXPERIMENTAL: this API may change without prior notice. 181 * 182 * Set the name of the thread. 183 * This API is a noop if the underlying platform does not 184 * support setting the thread name or the platform-specific 185 * API used to set the thread name fails. 186 * 187 * @param thread_id 188 * The id of the thread to set name. 189 * 190 * @param thread_name 191 * The name to set. Truncated to RTE_MAX_THREAD_NAME_LEN, 192 * including terminating NUL if necessary. 193 */ 194 __rte_experimental 195 void 196 rte_thread_set_name(rte_thread_t thread_id, const char *thread_name); 197 198 /** 199 * @warning 200 * @b EXPERIMENTAL: this API may change without prior notice. 201 * 202 * Check if 2 thread ids are equal. 203 * 204 * @param t1 205 * First thread id. 206 * 207 * @param t2 208 * Second thread id. 209 * 210 * @return 211 * If the ids are equal, return nonzero. 212 * Otherwise, return 0. 213 */ 214 __rte_experimental 215 int rte_thread_equal(rte_thread_t t1, rte_thread_t t2); 216 217 /** 218 * @warning 219 * @b EXPERIMENTAL: this API may change without prior notice. 220 * 221 * Initialize the attributes of a thread. 222 * These attributes can be passed to the rte_thread_create() function 223 * that will create a new thread and set its attributes according to attr. 224 * 225 * @param attr 226 * Thread attributes to initialize. 227 * 228 * @return 229 * On success, return 0. 230 * On failure, return a positive errno-style error number. 231 */ 232 __rte_experimental 233 int rte_thread_attr_init(rte_thread_attr_t *attr); 234 235 /** 236 * @warning 237 * @b EXPERIMENTAL: this API may change without prior notice. 238 * 239 * Set the thread priority value in the thread attributes pointed to 240 * by 'thread_attr'. 241 * 242 * @param thread_attr 243 * Points to the thread attributes in which priority will be updated. 244 * 245 * @param priority 246 * Points to the value of the priority to be set. 247 * 248 * @return 249 * On success, return 0. 250 * On failure, return a positive errno-style error number. 251 */ 252 __rte_experimental 253 int rte_thread_attr_set_priority(rte_thread_attr_t *thread_attr, 254 enum rte_thread_priority priority); 255 256 #ifdef RTE_HAS_CPUSET 257 258 /** 259 * @warning 260 * @b EXPERIMENTAL: this API may change without prior notice. 261 * 262 * Set the CPU affinity value in the thread attributes pointed to 263 * by 'thread_attr'. 264 * 265 * @param thread_attr 266 * Points to the thread attributes in which affinity will be updated. 267 * 268 * @param cpuset 269 * Points to the value of the affinity to be set. 270 * 271 * @return 272 * On success, return 0. 273 * On failure, return a positive errno-style error number. 274 */ 275 __rte_experimental 276 int rte_thread_attr_set_affinity(rte_thread_attr_t *thread_attr, 277 rte_cpuset_t *cpuset); 278 279 /** 280 * @warning 281 * @b EXPERIMENTAL: this API may change without prior notice. 282 * 283 * Get the value of CPU affinity that is set in the thread attributes pointed 284 * to by 'thread_attr'. 285 * 286 * @param thread_attr 287 * Points to the thread attributes from which affinity will be retrieved. 288 * 289 * @param cpuset 290 * Pointer to the memory that will store the affinity. 291 * 292 * @return 293 * On success, return 0. 294 * On failure, return a positive errno-style error number. 295 */ 296 __rte_experimental 297 int rte_thread_attr_get_affinity(rte_thread_attr_t *thread_attr, 298 rte_cpuset_t *cpuset); 299 300 /** 301 * @warning 302 * @b EXPERIMENTAL: this API may change without prior notice. 303 * 304 * Set the affinity of thread 'thread_id' to the cpu set 305 * specified by 'cpuset'. 306 * 307 * @param thread_id 308 * Id of the thread for which to set the affinity. 309 * 310 * @param cpuset 311 * Pointer to CPU affinity to set. 312 * 313 * @return 314 * On success, return 0. 315 * On failure, return a positive errno-style error number. 316 */ 317 __rte_experimental 318 int rte_thread_set_affinity_by_id(rte_thread_t thread_id, 319 const rte_cpuset_t *cpuset); 320 321 /** 322 * @warning 323 * @b EXPERIMENTAL: this API may change without prior notice. 324 * 325 * Get the affinity of thread 'thread_id' and store it 326 * in 'cpuset'. 327 * 328 * @param thread_id 329 * Id of the thread for which to get the affinity. 330 * 331 * @param cpuset 332 * Pointer for storing the affinity value. 333 * 334 * @return 335 * On success, return 0. 336 * On failure, return a positive errno-style error number. 337 */ 338 __rte_experimental 339 int rte_thread_get_affinity_by_id(rte_thread_t thread_id, 340 rte_cpuset_t *cpuset); 341 342 /** 343 * Set core affinity of the current thread. 344 * Support both EAL and non-EAL thread and update TLS. 345 * 346 * @param cpusetp 347 * Pointer to CPU affinity to set. 348 * @return 349 * On success, return 0; otherwise return -1; 350 */ 351 int rte_thread_set_affinity(rte_cpuset_t *cpusetp); 352 353 /** 354 * Get core affinity of the current thread. 355 * 356 * @param cpusetp 357 * Pointer to CPU affinity of current thread. 358 * It presumes input is not NULL, otherwise it causes panic. 359 * 360 */ 361 void rte_thread_get_affinity(rte_cpuset_t *cpusetp); 362 363 #endif /* RTE_HAS_CPUSET */ 364 365 /** 366 * @warning 367 * @b EXPERIMENTAL: this API may change without prior notice. 368 * 369 * Get the priority of a thread. 370 * 371 * @param thread_id 372 * Id of the thread for which to get priority. 373 * 374 * @param priority 375 * Location to store the retrieved priority. 376 * 377 * @return 378 * On success, return 0. 379 * On failure, return a positive errno-style error number. 380 */ 381 __rte_experimental 382 int rte_thread_get_priority(rte_thread_t thread_id, 383 enum rte_thread_priority *priority); 384 385 /** 386 * @warning 387 * @b EXPERIMENTAL: this API may change without prior notice. 388 * 389 * Set the priority of a thread. 390 * 391 * @param thread_id 392 * Id of the thread for which to set priority. 393 * 394 * @param priority 395 * Priority value to be set. 396 * 397 * @return 398 * On success, return 0. 399 * On failure, return a positive errno-style error number. 400 */ 401 __rte_experimental 402 int rte_thread_set_priority(rte_thread_t thread_id, 403 enum rte_thread_priority priority); 404 405 /** 406 * Create a TLS data key visible to all threads in the process. 407 * the created key is later used to get/set a value. 408 * and optional destructor can be set to be called when a thread exits. 409 * 410 * @param key 411 * Pointer to store the allocated key. 412 * @param destructor 413 * The function to be called when the thread exits. 414 * Ignored on Windows OS. 415 * 416 * @return 417 * On success, zero. 418 * On failure, a negative number and an error number is set in rte_errno. 419 * rte_errno can be: ENOMEM - Memory allocation error. 420 * ENOEXEC - Specific OS error. 421 */ 422 423 __rte_experimental 424 int rte_thread_key_create(rte_thread_key *key, 425 void (*destructor)(void *)); 426 427 /** 428 * Delete a TLS data key visible to all threads in the process. 429 * 430 * @param key 431 * The key allocated by rte_thread_key_create(). 432 * 433 * @return 434 * On success, zero. 435 * On failure, a negative number and an error number is set in rte_errno. 436 * rte_errno can be: EINVAL - Invalid parameter passed. 437 * ENOEXEC - Specific OS error. 438 */ 439 __rte_experimental 440 int rte_thread_key_delete(rte_thread_key key); 441 442 /** 443 * Set value bound to the TLS key on behalf of the calling thread. 444 * 445 * @param key 446 * The key allocated by rte_thread_key_create(). 447 * @param value 448 * The value bound to the rte_thread_key key for the calling thread. 449 * 450 * @return 451 * On success, zero. 452 * On failure, a negative number and an error number is set in rte_errno. 453 * rte_errno can be: EINVAL - Invalid parameter passed. 454 * ENOEXEC - Specific OS error. 455 */ 456 __rte_experimental 457 int rte_thread_value_set(rte_thread_key key, const void *value); 458 459 /** 460 * Get value bound to the TLS key on behalf of the calling thread. 461 * 462 * @param key 463 * The key allocated by rte_thread_key_create(). 464 * 465 * @return 466 * On success, value data pointer (can also be NULL). 467 * On failure, NULL and an error number is set in rte_errno. 468 * rte_errno can be: EINVAL - Invalid parameter passed. 469 * ENOEXEC - Specific OS error. 470 */ 471 __rte_experimental 472 void *rte_thread_value_get(rte_thread_key key); 473 474 #ifdef __cplusplus 475 } 476 #endif 477 478 #endif /* _RTE_THREAD_H_ */ 479