io_channel: Add a message passing callback
When a thread is registered, the user must provide a function pointer that can pass a message to that thread. Change-Id: I743b5e0d6e3b5118c0a68d2fcedbccdd6fb237f9 Signed-off-by: Ben Walker <benjamin.walker@intel.com> Reviewed-on: https://review.gerrithub.io/362067 Reviewed-by: Jim Harris <james.r.harris@intel.com> Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
This commit is contained in:
parent
f1c5344b32
commit
2ef5722f3c
@ -45,13 +45,23 @@
|
|||||||
struct spdk_thread;
|
struct spdk_thread;
|
||||||
struct spdk_io_channel;
|
struct spdk_io_channel;
|
||||||
|
|
||||||
|
typedef void (*spdk_thread_fn)(void *ctx);
|
||||||
|
typedef void (*spdk_thread_pass_msg)(spdk_thread_fn fn, void *ctx,
|
||||||
|
void *thread_ctx);
|
||||||
|
|
||||||
typedef int (*io_channel_create_cb_t)(void *io_device, void *ctx_buf);
|
typedef int (*io_channel_create_cb_t)(void *io_device, void *ctx_buf);
|
||||||
typedef void (*io_channel_destroy_cb_t)(void *io_device, void *ctx_buf);
|
typedef void (*io_channel_destroy_cb_t)(void *io_device, void *ctx_buf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Initializes the calling thread for I/O channel allocation.
|
* \brief Initializes the calling thread for I/O channel allocation.
|
||||||
|
*
|
||||||
|
* @param fn A function that may be called from any thread and is
|
||||||
|
* passed a function pointer (spdk_thread_fn) that must be
|
||||||
|
* called on the same thread that spdk_allocate_thread
|
||||||
|
* was called from.
|
||||||
|
* @param thread_ctx Context that will be passed to fn.
|
||||||
*/
|
*/
|
||||||
struct spdk_thread *spdk_allocate_thread(void);
|
struct spdk_thread *spdk_allocate_thread(spdk_thread_pass_msg fn, void *thread_ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Releases any resources related to the calling thread for I/O channel allocation.
|
* \brief Releases any resources related to the calling thread for I/O channel allocation.
|
||||||
@ -62,10 +72,22 @@ struct spdk_thread *spdk_allocate_thread(void);
|
|||||||
void spdk_free_thread(void);
|
void spdk_free_thread(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Get a handle to the current thread.
|
* \brief Get a handle to the current thread. This handle may be passed
|
||||||
|
* to other threads and used as the target of spdk_thread_send_msg().
|
||||||
*/
|
*/
|
||||||
struct spdk_thread *spdk_get_thread(void);
|
struct spdk_thread *spdk_get_thread(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Send a message to the given thread. The message
|
||||||
|
* may be sent asynchronously - i.e. spdk_thread_send_msg
|
||||||
|
* may return prior to `fn` being called.
|
||||||
|
*
|
||||||
|
* @param thread The target thread.
|
||||||
|
* @param fn This function will be called on the given thread.
|
||||||
|
* @param ctx This context will be passed to fn when called.
|
||||||
|
*/
|
||||||
|
void spdk_thread_send_msg(const struct spdk_thread *thread, spdk_thread_fn fn, void *ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Register the opaque io_device context as an I/O device.
|
* \brief Register the opaque io_device context as an I/O device.
|
||||||
*
|
*
|
||||||
|
@ -264,6 +264,27 @@ _spdk_poller_unregister_complete(struct spdk_poller *poller)
|
|||||||
free(poller);
|
free(poller);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_spdk_reactor_msg_passed(void *arg1, void *arg2)
|
||||||
|
{
|
||||||
|
spdk_thread_fn fn = arg1;
|
||||||
|
|
||||||
|
fn(arg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_spdk_reactor_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx)
|
||||||
|
{
|
||||||
|
uint32_t core;
|
||||||
|
struct spdk_event *event;
|
||||||
|
|
||||||
|
core = *(uint32_t *)thread_ctx;
|
||||||
|
|
||||||
|
event = spdk_event_allocate(core, _spdk_reactor_msg_passed, fn, ctx);
|
||||||
|
|
||||||
|
spdk_event_call(event);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* \brief This is the main function of the reactor thread.
|
* \brief This is the main function of the reactor thread.
|
||||||
@ -296,7 +317,7 @@ _spdk_reactor_run(void *arg)
|
|||||||
uint32_t sleep_us;
|
uint32_t sleep_us;
|
||||||
uint32_t timer_poll_count;
|
uint32_t timer_poll_count;
|
||||||
|
|
||||||
spdk_allocate_thread();
|
spdk_allocate_thread(_spdk_reactor_send_msg, &reactor->lcore);
|
||||||
set_reactor_thread_name(reactor->lcore);
|
set_reactor_thread_name(reactor->lcore);
|
||||||
SPDK_NOTICELOG("Reactor started on core %u on socket %u\n", reactor->lcore,
|
SPDK_NOTICELOG("Reactor started on core %u on socket %u\n", reactor->lcore,
|
||||||
reactor->socket_id);
|
reactor->socket_id);
|
||||||
|
@ -64,14 +64,18 @@ struct spdk_io_channel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct spdk_thread {
|
struct spdk_thread {
|
||||||
|
spdk_thread_pass_msg fn;
|
||||||
|
void *thread_ctx;
|
||||||
TAILQ_HEAD(, spdk_io_channel) io_channels;
|
TAILQ_HEAD(, spdk_io_channel) io_channels;
|
||||||
};
|
};
|
||||||
|
|
||||||
static __thread struct spdk_thread g_thread;
|
static __thread struct spdk_thread g_thread;
|
||||||
|
|
||||||
struct spdk_thread *
|
struct spdk_thread *
|
||||||
spdk_allocate_thread(void)
|
spdk_allocate_thread(spdk_thread_pass_msg fn, void *thread_ctx)
|
||||||
{
|
{
|
||||||
|
g_thread.fn = fn;
|
||||||
|
g_thread.thread_ctx = thread_ctx;
|
||||||
TAILQ_INIT(&g_thread.io_channels);
|
TAILQ_INIT(&g_thread.io_channels);
|
||||||
return &g_thread;
|
return &g_thread;
|
||||||
}
|
}
|
||||||
@ -88,6 +92,12 @@ spdk_get_thread(void)
|
|||||||
return &g_thread;
|
return &g_thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
spdk_thread_send_msg(const struct spdk_thread *thread, spdk_thread_fn fn, void *ctx)
|
||||||
|
{
|
||||||
|
thread->fn(fn, ctx, thread->thread_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
spdk_io_device_register(void *io_device, io_channel_create_cb_t create_cb,
|
spdk_io_device_register(void *io_device, io_channel_create_cb_t create_cb,
|
||||||
io_channel_destroy_cb_t destroy_cb, uint32_t ctx_size)
|
io_channel_destroy_cb_t destroy_cb, uint32_t ctx_size)
|
||||||
|
@ -48,6 +48,12 @@ int g_bserrno;
|
|||||||
struct spdk_xattr_names *g_names;
|
struct spdk_xattr_names *g_names;
|
||||||
int g_done;
|
int g_done;
|
||||||
|
|
||||||
|
static void
|
||||||
|
_bs_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx)
|
||||||
|
{
|
||||||
|
fn(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bs_op_complete(void *cb_arg, int bserrno)
|
bs_op_complete(void *cb_arg, int bserrno)
|
||||||
{
|
{
|
||||||
@ -963,7 +969,7 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_dev_buffer = calloc(1, DEV_BUFFER_SIZE);
|
g_dev_buffer = calloc(1, DEV_BUFFER_SIZE);
|
||||||
spdk_allocate_thread();
|
spdk_allocate_thread(_bs_send_msg, NULL);
|
||||||
CU_basic_set_mode(CU_BRM_VERBOSE);
|
CU_basic_set_mode(CU_BRM_VERBOSE);
|
||||||
CU_basic_run_tests();
|
CU_basic_run_tests();
|
||||||
num_failures = CU_get_number_of_failures();
|
num_failures = CU_get_number_of_failures();
|
||||||
|
@ -47,6 +47,12 @@ struct spdk_filesystem *g_fs;
|
|||||||
struct spdk_file *g_file;
|
struct spdk_file *g_file;
|
||||||
int g_fserrno;
|
int g_fserrno;
|
||||||
|
|
||||||
|
static void
|
||||||
|
_fs_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx)
|
||||||
|
{
|
||||||
|
fn(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fs_op_complete(void *ctx, int fserrno)
|
fs_op_complete(void *ctx, int fserrno)
|
||||||
{
|
{
|
||||||
@ -67,7 +73,7 @@ fs_init(void)
|
|||||||
struct spdk_bs_dev dev;
|
struct spdk_bs_dev dev;
|
||||||
|
|
||||||
init_dev(&dev);
|
init_dev(&dev);
|
||||||
spdk_allocate_thread();
|
spdk_allocate_thread(_fs_send_msg, NULL);
|
||||||
|
|
||||||
spdk_fs_init(&dev, NULL, fs_op_with_handle_complete, NULL);
|
spdk_fs_init(&dev, NULL, fs_op_with_handle_complete, NULL);
|
||||||
CU_ASSERT(g_fs != NULL);
|
CU_ASSERT(g_fs != NULL);
|
||||||
@ -109,7 +115,7 @@ fs_open(void)
|
|||||||
struct spdk_file *file;
|
struct spdk_file *file;
|
||||||
|
|
||||||
init_dev(&dev);
|
init_dev(&dev);
|
||||||
spdk_allocate_thread();
|
spdk_allocate_thread(_fs_send_msg, NULL);
|
||||||
|
|
||||||
spdk_fs_init(&dev, NULL, fs_op_with_handle_complete, NULL);
|
spdk_fs_init(&dev, NULL, fs_op_with_handle_complete, NULL);
|
||||||
CU_ASSERT(g_fs != NULL);
|
CU_ASSERT(g_fs != NULL);
|
||||||
@ -171,7 +177,7 @@ fs_truncate(void)
|
|||||||
struct spdk_bs_dev dev;
|
struct spdk_bs_dev dev;
|
||||||
|
|
||||||
init_dev(&dev);
|
init_dev(&dev);
|
||||||
spdk_allocate_thread();
|
spdk_allocate_thread(_fs_send_msg, NULL);
|
||||||
|
|
||||||
spdk_fs_init(&dev, NULL, fs_op_with_handle_complete, NULL);
|
spdk_fs_init(&dev, NULL, fs_op_with_handle_complete, NULL);
|
||||||
SPDK_CU_ASSERT_FATAL(g_fs != NULL);
|
SPDK_CU_ASSERT_FATAL(g_fs != NULL);
|
||||||
@ -224,7 +230,7 @@ fs_rename(void)
|
|||||||
struct spdk_bs_dev dev;
|
struct spdk_bs_dev dev;
|
||||||
|
|
||||||
init_dev(&dev);
|
init_dev(&dev);
|
||||||
spdk_allocate_thread();
|
spdk_allocate_thread(_fs_send_msg, NULL);
|
||||||
|
|
||||||
spdk_fs_init(&dev, NULL, fs_op_with_handle_complete, NULL);
|
spdk_fs_init(&dev, NULL, fs_op_with_handle_complete, NULL);
|
||||||
SPDK_CU_ASSERT_FATAL(g_fs != NULL);
|
SPDK_CU_ASSERT_FATAL(g_fs != NULL);
|
||||||
@ -377,7 +383,7 @@ channel_ops(void)
|
|||||||
struct spdk_io_channel *channel;
|
struct spdk_io_channel *channel;
|
||||||
|
|
||||||
init_dev(&dev);
|
init_dev(&dev);
|
||||||
spdk_allocate_thread();
|
spdk_allocate_thread(_fs_send_msg, NULL);
|
||||||
|
|
||||||
spdk_fs_init(&dev, NULL, fs_op_with_handle_complete, NULL);
|
spdk_fs_init(&dev, NULL, fs_op_with_handle_complete, NULL);
|
||||||
SPDK_CU_ASSERT_FATAL(g_fs != NULL);
|
SPDK_CU_ASSERT_FATAL(g_fs != NULL);
|
||||||
@ -405,7 +411,7 @@ channel_ops_sync(void)
|
|||||||
struct spdk_io_channel *channel;
|
struct spdk_io_channel *channel;
|
||||||
|
|
||||||
init_dev(&dev);
|
init_dev(&dev);
|
||||||
spdk_allocate_thread();
|
spdk_allocate_thread(_fs_send_msg, NULL);
|
||||||
|
|
||||||
spdk_fs_init(&dev, NULL, fs_op_with_handle_complete, NULL);
|
spdk_fs_init(&dev, NULL, fs_op_with_handle_complete, NULL);
|
||||||
SPDK_CU_ASSERT_FATAL(g_fs != NULL);
|
SPDK_CU_ASSERT_FATAL(g_fs != NULL);
|
||||||
|
@ -51,6 +51,12 @@ int g_fserrno;
|
|||||||
|
|
||||||
struct spdk_bs_dev g_dev;
|
struct spdk_bs_dev g_dev;
|
||||||
|
|
||||||
|
static void
|
||||||
|
_fs_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx)
|
||||||
|
{
|
||||||
|
fn(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
struct ut_request {
|
struct ut_request {
|
||||||
fs_request_fn fn;
|
fs_request_fn fn;
|
||||||
void *arg;
|
void *arg;
|
||||||
@ -144,7 +150,7 @@ cache_write(void)
|
|||||||
|
|
||||||
ut_send_request(_fs_init, NULL);
|
ut_send_request(_fs_init, NULL);
|
||||||
|
|
||||||
spdk_allocate_thread();
|
spdk_allocate_thread(_fs_send_msg, NULL);
|
||||||
channel = spdk_fs_alloc_io_channel_sync(g_fs);
|
channel = spdk_fs_alloc_io_channel_sync(g_fs);
|
||||||
|
|
||||||
rc = spdk_fs_open_file(g_fs, channel, "testfile", SPDK_BLOBFS_OPEN_CREATE, &g_file);
|
rc = spdk_fs_open_file(g_fs, channel, "testfile", SPDK_BLOBFS_OPEN_CREATE, &g_file);
|
||||||
@ -182,7 +188,7 @@ cache_write_null_buffer(void)
|
|||||||
|
|
||||||
ut_send_request(_fs_init, NULL);
|
ut_send_request(_fs_init, NULL);
|
||||||
|
|
||||||
spdk_allocate_thread();
|
spdk_allocate_thread(_fs_send_msg, NULL);
|
||||||
channel = spdk_fs_alloc_io_channel_sync(g_fs);
|
channel = spdk_fs_alloc_io_channel_sync(g_fs);
|
||||||
|
|
||||||
rc = spdk_fs_open_file(g_fs, channel, "testfile", SPDK_BLOBFS_OPEN_CREATE, &g_file);
|
rc = spdk_fs_open_file(g_fs, channel, "testfile", SPDK_BLOBFS_OPEN_CREATE, &g_file);
|
||||||
@ -214,7 +220,7 @@ cache_append_no_cache(void)
|
|||||||
|
|
||||||
ut_send_request(_fs_init, NULL);
|
ut_send_request(_fs_init, NULL);
|
||||||
|
|
||||||
spdk_allocate_thread();
|
spdk_allocate_thread(_fs_send_msg, NULL);
|
||||||
channel = spdk_fs_alloc_io_channel_sync(g_fs);
|
channel = spdk_fs_alloc_io_channel_sync(g_fs);
|
||||||
|
|
||||||
rc = spdk_fs_open_file(g_fs, channel, "testfile", SPDK_BLOBFS_OPEN_CREATE, &g_file);
|
rc = spdk_fs_open_file(g_fs, channel, "testfile", SPDK_BLOBFS_OPEN_CREATE, &g_file);
|
||||||
@ -256,7 +262,7 @@ spdk_thread(void *arg)
|
|||||||
{
|
{
|
||||||
struct ut_request *req;
|
struct ut_request *req;
|
||||||
|
|
||||||
spdk_allocate_thread();
|
spdk_allocate_thread(_fs_send_msg, NULL);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
pthread_mutex_lock(&g_mutex);
|
pthread_mutex_lock(&g_mutex);
|
||||||
|
@ -37,10 +37,16 @@
|
|||||||
|
|
||||||
#include "util/io_channel.c"
|
#include "util/io_channel.c"
|
||||||
|
|
||||||
|
static void
|
||||||
|
_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx)
|
||||||
|
{
|
||||||
|
fn(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
thread_alloc(void)
|
thread_alloc(void)
|
||||||
{
|
{
|
||||||
spdk_allocate_thread();
|
spdk_allocate_thread(_send_msg, NULL);
|
||||||
spdk_free_thread();
|
spdk_free_thread();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +106,7 @@ channel(void)
|
|||||||
struct spdk_io_channel *ch1, *ch2;
|
struct spdk_io_channel *ch1, *ch2;
|
||||||
void *ctx;
|
void *ctx;
|
||||||
|
|
||||||
spdk_allocate_thread();
|
spdk_allocate_thread(_send_msg, NULL);
|
||||||
spdk_io_device_register(&device1, create_cb_1, destroy_cb_1, sizeof(ctx1));
|
spdk_io_device_register(&device1, create_cb_1, destroy_cb_1, sizeof(ctx1));
|
||||||
spdk_io_device_register(&device2, create_cb_2, destroy_cb_2, sizeof(ctx2));
|
spdk_io_device_register(&device2, create_cb_2, destroy_cb_2, sizeof(ctx2));
|
||||||
spdk_io_device_register(&device3, create_cb_null, NULL, 0);
|
spdk_io_device_register(&device3, create_cb_null, NULL, 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user