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