/*-
* BSD LICENSE
*
- * Copyright (c) Intel Corporation.
- * All rights reserved.
+ * Copyright (c) Intel Corporation. All rights reserved.
+ * Copyright (c) 2020 Mellanox Technologies LTD. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#define SPDK_THREAD_INTERNAL_H_
#include "spdk/stdinc.h"
+#include "spdk/thread.h"
-struct spdk_thread;
+#define SPDK_MAX_POLLER_NAME_LEN 256
+#define SPDK_MAX_THREAD_NAME_LEN 256
-/**
- * Force the current system thread to act as if executing the given SPDK thread.
- * This is only used for unit testing.
- */
-void spdk_set_thread(struct spdk_thread *thread);
+enum spdk_poller_state {
+ /* The poller is registered with a thread but not currently executing its fn. */
+ SPDK_POLLER_STATE_WAITING,
+
+ /* The poller is currently running its fn. */
+ SPDK_POLLER_STATE_RUNNING,
+
+ /* The poller was unregistered during the execution of its fn. */
+ SPDK_POLLER_STATE_UNREGISTERED,
+
+ /* The poller is in the process of being paused. It will be paused
+ * during the next time it's supposed to be executed.
+ */
+ SPDK_POLLER_STATE_PAUSING,
+
+ /* The poller is registered but currently paused. It's on the
+ * paused_pollers list.
+ */
+ SPDK_POLLER_STATE_PAUSED,
+};
+
+struct spdk_poller {
+ TAILQ_ENTRY(spdk_poller) tailq;
+
+ /* Current state of the poller; should only be accessed from the poller's thread. */
+ enum spdk_poller_state state;
+
+ uint64_t period_ticks;
+ uint64_t next_run_tick;
+ uint64_t run_count;
+ uint64_t busy_count;
+ spdk_poller_fn fn;
+ void *arg;
+ struct spdk_thread *thread;
+
+ char name[SPDK_MAX_POLLER_NAME_LEN + 1];
+};
+
+enum spdk_thread_state {
+ /* The thread is pocessing poller and message by spdk_thread_poll(). */
+ SPDK_THREAD_STATE_RUNNING,
+
+ /* The thread is in the process of termination. It reaps unregistering
+ * poller are releasing I/O channel.
+ */
+ SPDK_THREAD_STATE_EXITING,
+
+ /* The thread is exited. It is ready to call spdk_thread_destroy(). */
+ SPDK_THREAD_STATE_EXITED,
+};
+
+struct spdk_thread {
+ uint64_t tsc_last;
+ struct spdk_thread_stats stats;
+ /*
+ * Contains pollers actively running on this thread. Pollers
+ * are run round-robin. The thread takes one poller from the head
+ * of the ring, executes it, then puts it back at the tail of
+ * the ring.
+ */
+ TAILQ_HEAD(active_pollers_head, spdk_poller) active_pollers;
+ /**
+ * Contains pollers running on this thread with a periodic timer.
+ */
+ TAILQ_HEAD(timed_pollers_head, spdk_poller) timed_pollers;
+ /*
+ * Contains paused pollers. Pollers on this queue are waiting until
+ * they are resumed (in which case they're put onto the active/timer
+ * queues) or unregistered.
+ */
+ TAILQ_HEAD(paused_pollers_head, spdk_poller) paused_pollers;
+ struct spdk_ring *messages;
+ SLIST_HEAD(, spdk_msg) msg_cache;
+ size_t msg_cache_count;
+ spdk_msg_fn critical_msg;
+ uint64_t id;
+ enum spdk_thread_state state;
+
+ TAILQ_HEAD(, spdk_io_channel) io_channels;
+ TAILQ_ENTRY(spdk_thread) tailq;
+
+ char name[SPDK_MAX_THREAD_NAME_LEN + 1];
+ struct spdk_cpuset cpumask;
+ uint64_t exit_timeout_tsc;
+
+ /* User context allocated at the end */
+ uint8_t ctx[0];
+};
+
+const char *spdk_poller_state_str(enum spdk_poller_state state);
+
+const char *spdk_io_device_get_name(struct io_device *dev);
#endif /* SPDK_THREAD_INTERNAL_H_ */