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