[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH 22/23] lib/ukschedpreempt: Handle timer interrupts
Timer interrupts are used to preempt threads if the time slice of the current thread time slice expired. In order to do this, the scheduler needs to register its handler so that it will be called whenever a timer interrupt occurs. Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx> --- lib/ukschedpreempt/schedpreempt.c | 57 +++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/lib/ukschedpreempt/schedpreempt.c b/lib/ukschedpreempt/schedpreempt.c index ef0cbabe..37317d1f 100644 --- a/lib/ukschedpreempt/schedpreempt.c +++ b/lib/ukschedpreempt/schedpreempt.c @@ -85,6 +85,56 @@ static void schedpreempt_schedule(struct uk_sched *s, uk_sched_thread_switch(s, current, next); } +static +void schedpreempt_timer_tick(void *arg) +{ + struct uk_sched *s; + struct schedpreempt_private *prv; + struct uk_thread *current, *t, *tmp; + struct preempt_thread_attr *attr; + __snsec now; + + UK_ASSERT(arg != NULL); + s = arg; + + current = uk_thread_current(); + UK_ASSERT(current != NULL); + + prv = s->prv; + + /* Wake up sleeping threads */ + now = ukplat_monotonic_clock(); + UK_TAILQ_FOREACH_SAFE(t, &prv->sleeping_threads, thread_list, tmp) { + if (t->wakeup_time <= now) + uk_thread_wake(t); + } + + if (current == uk_sched_get_idle(s)) + /* Nothing to schedule, idle thread is running */ + goto out; + + attr = current->sched_prv; + UK_ASSERT(attr != NULL); + UK_ASSERT(attr->timeslice > 0); + + if (attr->timeslice <= (int) UKPLAT_TIME_TICK_MSEC) { + /* Time slice expiring: renew */ + attr->timeslice = attr->timeslice_length; + + /* Check if we have other threads to schedule */ + if (!prioq_empty_for_prio(&prv->ready_queue, attr->prio)) { + schedpreempt_schedule(s, current); + return; + } + + } else + /* Update time slice */ + attr->timeslice -= (int) UKPLAT_TIME_TICK_MSEC; + +out: + return; +} + static struct preempt_thread_attr *preempt_thread_attr_create(struct uk_alloc *a, const struct uk_thread_attr *attr) @@ -292,6 +342,7 @@ struct uk_sched *uk_schedpreempt_init(struct uk_alloc *a) { struct uk_sched *sched = NULL; struct schedpreempt_private *prv = NULL; + int rc; uk_pr_info("Initializing preemptive scheduler\n"); @@ -318,6 +369,12 @@ struct uk_sched *uk_schedpreempt_init(struct uk_alloc *a) schedpreempt_thread_set_tslice, schedpreempt_thread_get_tslice); + rc = ukplat_time_schedule_register(schedpreempt_timer_tick, sched); + if (rc) { + uk_pr_warn("Could not register schedule handler."); + goto out_err; + } + return sched; out_err: -- 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 |