[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 |