[2/2] eal/windows: fix create thread failure behavior
Checks
Commit Message
In rte_thread_create setting affinity after CreateThread may fail. Such
a failure is reported but strands the newly created thread in a
suspended state.
Resolve the above issue by notifying the newly created thread that
it should terminate as soon as it is resumed, while still continuing to
free the ctx.
Fixes: ce6e911d20f6 ("eal: add thread lifetime API")
Cc: stable@dpdk.org
Cc: roretzla@linux.microsoft.com
Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
---
lib/eal/windows/rte_thread.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
@@ -19,6 +19,7 @@ struct eal_tls_key {
struct thread_routine_ctx {
rte_thread_func thread_func;
+ bool thread_init_failed;
void *routine_args;
};
@@ -167,9 +168,13 @@ struct thread_routine_ctx {
thread_func_wrapper(void *arg)
{
struct thread_routine_ctx ctx = *(struct thread_routine_ctx *)arg;
+ const bool thread_exit = __atomic_load_n(&ctx.thread_init_failed, __ATOMIC_ACQUIRE);
free(arg);
+ if (thread_exit)
+ return 0;
+
return (DWORD)ctx.thread_func(ctx.routine_args);
}
@@ -183,6 +188,7 @@ struct thread_routine_ctx {
HANDLE thread_handle = NULL;
GROUP_AFFINITY thread_affinity;
struct thread_routine_ctx *ctx;
+ bool thread_exit = false;
ctx = calloc(1, sizeof(*ctx));
if (ctx == NULL) {
@@ -192,6 +198,7 @@ struct thread_routine_ctx {
}
ctx->routine_args = args;
ctx->thread_func = thread_func;
+ ctx->thread_init_failed = false;
thread_handle = CreateThread(NULL, 0, thread_func_wrapper, ctx,
CREATE_SUSPENDED, &tid);
@@ -209,23 +216,29 @@ struct thread_routine_ctx {
);
if (ret != 0) {
RTE_LOG(DEBUG, EAL, "Unable to convert cpuset to thread affinity\n");
- goto cleanup;
+ thread_exit = true;
+ goto resume_thread;
}
if (!SetThreadGroupAffinity(thread_handle,
&thread_affinity, NULL)) {
ret = thread_log_last_error("SetThreadGroupAffinity()");
- goto cleanup;
+ thread_exit = true;
+ goto resume_thread;
}
}
ret = rte_thread_set_priority(*thread_id,
thread_attr->priority);
if (ret != 0) {
RTE_LOG(DEBUG, EAL, "Unable to set thread priority\n");
- goto cleanup;
+ thread_exit = true;
+ goto resume_thread;
}
}
+resume_thread:
+ __atomic_store_n(&ctx->thread_init_failed, thread_exit, __ATOMIC_RELEASE);
+
if (ResumeThread(thread_handle) == (DWORD)-1) {
ret = thread_log_last_error("ResumeThread()");
goto cleanup;