Commit 2ef5722f authored by Ben Walker's avatar Ben Walker
Browse files

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: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-on: https://review.gerrithub.io/362067


Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
parent f1c5344b
Loading
Loading
Loading
Loading
+24 −2
Original line number Diff line number Diff line
@@ -45,13 +45,23 @@
struct spdk_thread;
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 void (*io_channel_destroy_cb_t)(void *io_device, void *ctx_buf);

/**
 * \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.
@@ -62,10 +72,22 @@ struct spdk_thread *spdk_allocate_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);

/**
 * \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.
 *
+22 −1
Original line number Diff line number Diff line
@@ -264,6 +264,27 @@ _spdk_poller_unregister_complete(struct spdk_poller *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.
@@ -296,7 +317,7 @@ _spdk_reactor_run(void *arg)
	uint32_t		sleep_us;
	uint32_t 		timer_poll_count;

	spdk_allocate_thread();
	spdk_allocate_thread(_spdk_reactor_send_msg, &reactor->lcore);
	set_reactor_thread_name(reactor->lcore);
	SPDK_NOTICELOG("Reactor started on core %u on socket %u\n", reactor->lcore,
		       reactor->socket_id);
+11 −1
Original line number Diff line number Diff line
@@ -64,14 +64,18 @@ struct spdk_io_channel {
};

struct spdk_thread {
	spdk_thread_pass_msg fn;
	void *thread_ctx;
	TAILQ_HEAD(, spdk_io_channel) io_channels;
};

static __thread struct spdk_thread g_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);
	return &g_thread;
}
@@ -88,6 +92,12 @@ spdk_get_thread(void)
	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
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)
+7 −1
Original line number Diff line number Diff line
@@ -48,6 +48,12 @@ int g_bserrno;
struct spdk_xattr_names *g_names;
int g_done;

static void
_bs_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx)
{
	fn(ctx);
}

static void
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);
	spdk_allocate_thread();
	spdk_allocate_thread(_bs_send_msg, NULL);
	CU_basic_set_mode(CU_BRM_VERBOSE);
	CU_basic_run_tests();
	num_failures = CU_get_number_of_failures();
+12 −6
Original line number Diff line number Diff line
@@ -47,6 +47,12 @@ struct spdk_filesystem *g_fs;
struct spdk_file *g_file;
int g_fserrno;

static void
_fs_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx)
{
	fn(ctx);
}

static void
fs_op_complete(void *ctx, int fserrno)
{
@@ -67,7 +73,7 @@ fs_init(void)
	struct spdk_bs_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);
	CU_ASSERT(g_fs != NULL);
@@ -109,7 +115,7 @@ fs_open(void)
	struct spdk_file *file;

	init_dev(&dev);
	spdk_allocate_thread();
	spdk_allocate_thread(_fs_send_msg, NULL);

	spdk_fs_init(&dev, NULL, fs_op_with_handle_complete, NULL);
	CU_ASSERT(g_fs != NULL);
@@ -171,7 +177,7 @@ fs_truncate(void)
	struct spdk_bs_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_CU_ASSERT_FATAL(g_fs != NULL);
@@ -224,7 +230,7 @@ fs_rename(void)
	struct spdk_bs_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_CU_ASSERT_FATAL(g_fs != NULL);
@@ -377,7 +383,7 @@ channel_ops(void)
	struct spdk_io_channel *channel;

	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_CU_ASSERT_FATAL(g_fs != NULL);
@@ -405,7 +411,7 @@ channel_ops_sync(void)
	struct spdk_io_channel *channel;

	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_CU_ASSERT_FATAL(g_fs != NULL);
Loading