From 835d21a2d0242601ce732eac3f2aee3e365ec663 Mon Sep 17 00:00:00 2001 From: Ben Walker Date: Thu, 2 May 2019 12:44:32 -0700 Subject: [PATCH] thread: Allow thread schedule callback to fail Change-Id: Id391c2c03804dda0ad354d98dfe0a75fb4d3d324 Signed-off-by: Ben Walker Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/453012 Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris --- include/spdk/thread.h | 2 +- lib/event/reactor.c | 4 ++- lib/thread/thread.c | 18 ++++++++++- test/unit/lib/thread/thread.c/thread_ut.c | 37 ++++++++++++++++++++--- 4 files changed, 53 insertions(+), 8 deletions(-) diff --git a/include/spdk/thread.h b/include/spdk/thread.h index 3b1d7f738..35b5578fd 100644 --- a/include/spdk/thread.h +++ b/include/spdk/thread.h @@ -58,7 +58,7 @@ struct spdk_poller; * * \param thread The new spdk_thread. */ -typedef void (*spdk_new_thread_fn)(struct spdk_thread *thread); +typedef int (*spdk_new_thread_fn)(struct spdk_thread *thread); /** * A function that will be called on the target thread. diff --git a/lib/event/reactor.c b/lib/event/reactor.c index 00213c159..712969a49 100644 --- a/lib/event/reactor.c +++ b/lib/event/reactor.c @@ -400,7 +400,7 @@ _schedule_thread(void *arg1, void *arg2) TAILQ_INSERT_TAIL(&reactor->threads, lw_thread, link); } -static void +static int spdk_reactor_schedule_thread(struct spdk_thread *thread) { uint32_t core; @@ -421,6 +421,8 @@ spdk_reactor_schedule_thread(struct spdk_thread *thread) evt = spdk_event_allocate(core, _schedule_thread, lw_thread, NULL); spdk_event_call(evt); + + return 0; } int diff --git a/lib/thread/thread.c b/lib/thread/thread.c index ba367cd65..492b6b01c 100644 --- a/lib/thread/thread.c +++ b/lib/thread/thread.c @@ -178,7 +178,11 @@ spdk_thread_lib_fini(void) if (g_spdk_msg_mempool) { spdk_mempool_free(g_spdk_msg_mempool); + g_spdk_msg_mempool = NULL; } + + g_new_thread_fn = NULL; + g_ctx_sz = 0; } struct spdk_thread * @@ -248,7 +252,19 @@ spdk_thread_create(const char *name, struct spdk_cpuset *cpumask) pthread_mutex_unlock(&g_devlist_mutex); if (g_new_thread_fn) { - g_new_thread_fn(thread); + rc = g_new_thread_fn(thread); + if (rc != 0) { + spdk_cpuset_free(thread->cpumask); + spdk_ring_free(thread->messages); + spdk_mempool_put_bulk(g_spdk_msg_mempool, (void **)msgs, SPDK_MSG_MEMPOOL_CACHE_SIZE); + free(thread->name); + pthread_mutex_lock(&g_devlist_mutex); + TAILQ_REMOVE(&g_threads, thread, tailq); + g_thread_count--; + pthread_mutex_unlock(&g_devlist_mutex); + free(thread); + return NULL; + } } return thread; diff --git a/test/unit/lib/thread/thread.c/thread_ut.c b/test/unit/lib/thread/thread.c/thread_ut.c index bd74be263..3b8706d25 100644 --- a/test/unit/lib/thread/thread.c/thread_ut.c +++ b/test/unit/lib/thread/thread.c/thread_ut.c @@ -40,14 +40,41 @@ #include "thread/thread.c" #include "common/lib/ut_multithread.c" +static int g_sched_rc = 0; + +static int +_thread_schedule(struct spdk_thread *thread) +{ + return g_sched_rc; +} + static void thread_alloc(void) { - CU_ASSERT(TAILQ_EMPTY(&g_threads)); - allocate_threads(1); - CU_ASSERT(!TAILQ_EMPTY(&g_threads)); - free_threads(); - CU_ASSERT(TAILQ_EMPTY(&g_threads)); + struct spdk_thread *thread; + + /* No schedule callback */ + spdk_thread_lib_init(NULL, 0); + thread = spdk_thread_create(NULL, NULL); + CU_ASSERT(thread != NULL); + spdk_thread_exit(thread); + spdk_thread_lib_fini(); + + /* Schedule callback exists */ + spdk_thread_lib_init(_thread_schedule, 0); + + /* Scheduling succeeds */ + g_sched_rc = 0; + thread = spdk_thread_create(NULL, NULL); + CU_ASSERT(thread != NULL); + spdk_thread_exit(thread); + + /* Scheduling fails */ + g_sched_rc = -1; + thread = spdk_thread_create(NULL, NULL); + CU_ASSERT(thread == NULL); + + spdk_thread_lib_fini(); } static void