typedef void (*uk_sched_thread_woken_func_t)
(struct uk_sched *s, struct uk_thread *t);
+typedef const struct uk_thread * (*uk_sched_idle_thread_func_t)
+ (struct uk_sched *s, unsigned int proc_id);
+
typedef int (*uk_sched_start_t)(struct uk_sched *s, struct uk_thread *main);
struct uk_sched {
uk_sched_thread_remove_func_t thread_remove;
uk_sched_thread_blocked_func_t thread_blocked;
uk_sched_thread_woken_func_t thread_woken;
+ uk_sched_idle_thread_func_t idle_thread;
uk_sched_start_t sched_start;
s->thread_woken(s, t);
}
+/**
+ * Returns the reference to the idle thread that is responsible for
+ * the processing unit `proc_id`. Please note that `proc_id` is not
+ * a logical core ID; it is a linear increasing number over the managed
+ * logical cores by the scheduler instance `s`.
+ * It is possible that a scheduler implementation does not operate with idle
+ * threads and returns `NULL`.
+ */
+static inline const struct uk_thread *uk_sched_idle_thread(struct uk_sched *s,
+ unsigned int proc_id)
+{
+ UK_ASSERT(s);
+
+ if (unlikely(!s->idle_thread))
+ return NULL;
+
+ return s->idle_thread(s, proc_id);
+}
+
/**
* Create a main thread from current context and call thread starter function
*/
#define uk_sched_init(s, start_func, yield_func, \
thread_add_func, thread_remove_func, \
thread_blocked_func, thread_woken_func, \
- def_allocator) \
+ idle_thread_func, def_allocator) \
do { \
(s)->sched_start = start_func; \
(s)->yield = yield_func; \
(s)->thread_remove = thread_remove_func; \
(s)->thread_blocked = thread_blocked_func; \
(s)->thread_woken = thread_woken_func; \
+ (s)->idle_thread = idle_thread_func; \
uk_sched_register((s)); \
\
(s)->a = (def_allocator); \