From aaa9a27851d5365344663cb28174031244fb472c Mon Sep 17 00:00:00 2001 From: Ben Walker Date: Tue, 15 Jan 2019 13:39:06 -0700 Subject: [PATCH] thread: Add a notification callback when threads are created Nothing implements the callback just yet, but it will be used for dynamic thread creation. Change-Id: I088f2bc40e1405cd5b9973b9110608f49c8abd68 Signed-off-by: Ben Walker Reviewed-on: https://review.gerrithub.io/c/440594 Tested-by: SPDK CI Jenkins Chandler-Test-Pool: SPDK Automated Test System Reviewed-by: Darek Stojaczyk Reviewed-by: Jim Harris Reviewed-by: Shuhei Matsumoto --- examples/bdev/fio_plugin/fio_plugin.c | 2 +- include/spdk/thread.h | 14 +++++++++++++- lib/event/app.c | 2 +- lib/thread/thread.c | 11 ++++++++++- 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/examples/bdev/fio_plugin/fio_plugin.c b/examples/bdev/fio_plugin/fio_plugin.c index f88709359..c7aa0ae8b 100644 --- a/examples/bdev/fio_plugin/fio_plugin.c +++ b/examples/bdev/fio_plugin/fio_plugin.c @@ -280,7 +280,7 @@ spdk_init_thread_poll(void *arg) } spdk_unaffinitize_thread(); - spdk_thread_lib_init(); + spdk_thread_lib_init(NULL); /* Create an SPDK thread temporarily */ rc = spdk_fio_init_thread(&td); diff --git a/include/spdk/thread.h b/include/spdk/thread.h index a40146c0e..c53903b51 100644 --- a/include/spdk/thread.h +++ b/include/spdk/thread.h @@ -50,6 +50,15 @@ struct spdk_thread; struct spdk_io_channel_iter; struct spdk_poller; +/** + * A function that is called each time a new thread is created. + * The implementor of this function should frequently call + * spdk_thread_poll() on the thread provided. + * + * \param thread The new spdk_thread. + */ +typedef void (*spdk_new_thread_fn)(struct spdk_thread *thread); + /** * A function that will be called on the target thread. * @@ -166,9 +175,12 @@ struct spdk_io_channel { /** * Initialize the threading library. Must be called once prior to allocating any threads. * + * \param new_thread_fn Called each time a new SPDK thread is created. The implementor + * is expected to frequently call spdk_thread_poll() on the provided thread. + * * \return 0 on success. Negated errno on failure. */ -int spdk_thread_lib_init(void); +int spdk_thread_lib_init(spdk_new_thread_fn new_thread_fn); /** * Release all resources associated with this library. diff --git a/lib/event/app.c b/lib/event/app.c index a3073112c..9817eb7b8 100644 --- a/lib/event/app.c +++ b/lib/event/app.c @@ -624,7 +624,7 @@ spdk_app_start(struct spdk_app_opts *opts, spdk_event_fn start_fn, spdk_log_open(); SPDK_NOTICELOG("Total cores available: %d\n", spdk_env_get_core_count()); - spdk_thread_lib_init(); + spdk_thread_lib_init(NULL); /* * If mask not specified on command line or in configuration file, diff --git a/lib/thread/thread.c b/lib/thread/thread.c index 02b7cc562..11592f43c 100644 --- a/lib/thread/thread.c +++ b/lib/thread/thread.c @@ -54,6 +54,8 @@ static pthread_mutex_t g_devlist_mutex = PTHREAD_MUTEX_INITIALIZER; +static spdk_new_thread_fn g_new_thread_fn = NULL; + struct io_device { void *io_device; char *name; @@ -147,10 +149,13 @@ _set_thread_name(const char *thread_name) } int -spdk_thread_lib_init(void) +spdk_thread_lib_init(spdk_new_thread_fn new_thread_fn) { char mempool_name[SPDK_MAX_MEMZONE_NAME_LEN]; + assert(g_new_thread_fn == NULL); + g_new_thread_fn = new_thread_fn; + snprintf(mempool_name, sizeof(mempool_name), "msgpool_%d", getpid()); g_spdk_msg_mempool = spdk_mempool_create(mempool_name, 262144 - 1, /* Power of 2 minus 1 is optimal for memory consumption */ @@ -215,6 +220,10 @@ spdk_allocate_thread(const char *name) g_thread_count++; pthread_mutex_unlock(&g_devlist_mutex); + if (g_new_thread_fn) { + g_new_thread_fn(thread); + } + return thread; }