|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH 20/23] lib/ukschedpreempt: Schedule threads
This patch adds the scheduling core function. We also add yield as it is, more
or less, a wrapper over the scheduling function.
Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx>
---
lib/ukschedpreempt/schedpreempt.c | 58 ++++++++++++++++++++++++++++++-
1 file changed, 57 insertions(+), 1 deletion(-)
diff --git a/lib/ukschedpreempt/schedpreempt.c
b/lib/ukschedpreempt/schedpreempt.c
index c6963b2f..0a01c3df 100644
--- a/lib/ukschedpreempt/schedpreempt.c
+++ b/lib/ukschedpreempt/schedpreempt.c
@@ -33,6 +33,7 @@
*/
#include <uk/plat/lcpu.h>
+#include <uk/plat/memory.h>
#include <uk/plat/time.h>
#include <uk/schedpreempt.h>
#include <uk/prioq.h>
@@ -44,6 +45,45 @@ struct schedpreempt_private {
struct uk_thread_list sleeping_threads;
};
+static void schedpreempt_schedule(struct uk_sched *s,
+ struct uk_thread *current)
+{
+ struct schedpreempt_private *prv;
+ struct preempt_thread_attr *attr;
+ struct uk_thread *next;
+ int current_runnable;
+ prio_t highest_prio;
+
+ UK_ASSERT(s != NULL);
+ UK_ASSERT(current != NULL);
+
+ prv = s->prv;
+ attr = current->sched_prv;
+
+ highest_prio = prioq_highest_prio(&prv->ready_queue);
+
+ current_runnable = is_runnable(current);
+ if (current_runnable && attr->prio > highest_prio) {
+ /* There is no thread with higher priority, keep running ... */
+ return;
+ }
+
+ /* Pick up the next thread */
+ if (highest_prio >= UK_THREAD_ATTR_PRIO_MIN)
+ next = prioq_pop_for_prio(&prv->ready_queue, highest_prio);
+ else
+ next = uk_sched_get_idle(s);
+
+ /* Put current thread in the ready queue if runnable */
+ if (current_runnable && current != uk_sched_get_idle(s))
+ prioq_enqueue(&prv->ready_queue, current);
+
+ /* Notify the platform about the new thread */
+ ukplat_stack_set_current_thread(next);
+
+ /* Make the switch */
+ uk_sched_thread_switch(s, current, next);
+}
static
struct preempt_thread_attr *preempt_thread_attr_create(struct uk_alloc *a,
@@ -119,6 +159,13 @@ void schedpreempt_thread_remove(struct uk_sched *s, struct
uk_thread *t)
uk_thread_exit(t);
UK_TAILQ_INSERT_HEAD(&s->exited_threads, t, thread_list);
+ if (t == uk_thread_current()) {
+ /* thread exiting */
+ schedpreempt_schedule(s, t);
+ UK_CRASH("schedule() returned!\n");
+ }
+ /* else thread killed */
+
ukplat_lcpu_restore_irqf(flags);
}
@@ -204,6 +251,15 @@ int schedpreempt_thread_get_tslice(struct uk_sched *s
__unused,
return 0;
}
+static void schedpreempt_yield(struct uk_sched *s)
+{
+ unsigned long flags;
+
+ flags = ukplat_lcpu_save_irqf();
+ schedpreempt_schedule(s, uk_thread_current());
+ ukplat_lcpu_restore_irqf(flags);
+}
+
struct uk_sched *uk_schedpreempt_init(struct uk_alloc *a)
{
struct uk_sched *sched = NULL;
@@ -222,7 +278,7 @@ struct uk_sched *uk_schedpreempt_init(struct uk_alloc *a)
UK_TAILQ_INIT(&prv->sleeping_threads);
uk_sched_init(sched,
- NULL,
+ schedpreempt_yield,
schedpreempt_thread_add,
schedpreempt_thread_remove,
schedpreempt_thread_blocked,
--
2.20.1
_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |