| 283 | } |
| 284 | |
| 285 | int |
| 286 | rte_thread_create_control(rte_thread_t *thread, const char *name, |
| 287 | rte_thread_func start_routine, void *arg) |
| 288 | { |
| 289 | struct control_thread_params *params; |
| 290 | enum __rte_ctrl_thread_status ctrl_thread_status; |
| 291 | int ret; |
| 292 | |
| 293 | params = malloc(sizeof(*params)); |
| 294 | if (params == NULL) |
| 295 | return -ENOMEM; |
| 296 | |
| 297 | params->start_routine = start_routine; |
| 298 | params->arg = arg; |
| 299 | params->ret = 0; |
| 300 | params->status = CTRL_THREAD_LAUNCHING; |
| 301 | |
| 302 | ret = rte_thread_create(thread, NULL, control_thread_start, params); |
| 303 | if (ret != 0) { |
| 304 | free(params); |
| 305 | return -ret; |
| 306 | } |
| 307 | |
| 308 | if (name != NULL) |
| 309 | rte_thread_set_name(*thread, name); |
| 310 | |
| 311 | /* Wait for the control thread to initialize successfully */ |
| 312 | while ((ctrl_thread_status = |
| 313 | rte_atomic_load_explicit(¶ms->status, |
| 314 | rte_memory_order_acquire)) == CTRL_THREAD_LAUNCHING) { |
| 315 | rte_delay_us_sleep(1); |
| 316 | } |
| 317 | |
| 318 | /* Check if the control thread encountered an error */ |
| 319 | if (ctrl_thread_status == CTRL_THREAD_ERROR) { |
| 320 | /* ctrl thread is exiting */ |
| 321 | rte_thread_join(*thread, NULL); |
| 322 | } |
| 323 | |
| 324 | ret = params->ret; |
| 325 | free(params); |
| 326 | |
| 327 | return ret; |
| 328 | } |
| 329 | |
| 330 | static void |
| 331 | add_internal_prefix(char *prefixed_name, const char *name, size_t size) |