thread: Allow thread schedule callback to fail

Change-Id: Id391c2c03804dda0ad354d98dfe0a75fb4d3d324
Signed-off-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/453012
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Ben Walker 2019-05-02 12:44:32 -07:00 committed by Jim Harris
parent a1d4dcdc85
commit 835d21a2d0
4 changed files with 53 additions and 8 deletions

View File

@ -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.

View File

@ -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

View File

@ -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;

View File

@ -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