[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Minios-devel] [UNIKRAFT PATCH 22/23] lib/ukschedpreempt: Handle timer interrupts


  • To: minios-devel@xxxxxxxxxxxxx
  • From: Costin Lupu <costin.lupu@xxxxxxxxx>
  • Date: Mon, 8 Jul 2019 11:33:51 +0300
  • Cc: felipe.huici@xxxxxxxxx, simon.kuenzer@xxxxxxxxx
  • Delivery-date: Mon, 08 Jul 2019 08:53:39 +0000
  • Ironport-phdr: 9a23:CzOs3BHsaYcgGaY4W50EEZ1GYnF86YWxBRYc798ds5kLTJ7zoMmwAkXT6L1XgUPTWs2DsrQY0rCQ7/irATBIyK3CmUhKSIZLWR4BhJdetC0bK+nBN3fGKuX3ZTcxBsVIWQwt1Xi6NU9IBJS2PAWK8TW94jEIBxrwKxd+KPjrFY7OlcS30P2594HObwlSizexfK1+IA+5oAnNucUanYRvIbstxxXUpXdFZ/5Yzn5yK1KJmBb86Maw/Jp9/ClVpvks6c1OX7jkcqohVbBXAygoPG4z5M3wqBnMVhCP6WcGUmUXiRVHHQ7I5wznU5jrsyv6su192DSGPcDzULs5Vyiu47ttRRT1jioMKjw3/3zNisFojKxVvg+vqRJ8zYDTYo6VOuFzcr/Bcd4AWWZMRNpdWzBHD4ihb4UPFe0BPeNAooTjoFsOtge+BQiqBOjyzDFIm2f23bAn2OkmDQ7G2xcgH84PsHTSttn1MLoSUfiozKTT0TrDdOla2S/g6IfTaBwhu/aMUKt2fMHMykcvDxvIgkifpID4JT+Y1eQAv3KF4+Z+V++jkWAqpxlsrjWg28sgkIrEi4IPxlza+yh0zpw5KcC3RUJlZ9OvDYFeuDuAN4RsR8MvW2RouCEnxbIYoZO7Zy0KyIg/xx7YdvyHb5CE4hL9W+aVJjd1nGxleLeliBaz9Uis0PHzVtKu3FZSsypKicPAtmoK1xDL68iHTOVy/lu51DqS2A3f9/tILEM0mKbBNZIt3Lw9moAdvEjbGy/5gkT2jKuYdkU+/eio7vzqbanhpp+HK490iwf+Pr4qmsyiGeQ4LxMDUHSA+eimzL3j4Fb2TK9Qjv0xiqXZqozVJdwHpq6lBA9YyoMj6xe5Dzen19QYhmALI09bdxKZkYfpP0rDIPT5Dfekn1Ssiy1nxv/YMb3nGJnNKWLDkLj5d7Zn90Fc0BYzzcxY559MBLEOPvbzWk7ptNPGFBM5MxG0w+f7B9V8zY4eX3yADbOdMKzIqlCE/PwgI/SUbo8PpDn9M+Ql5+LpjXIhgl8dfKyp3ZwRaHyiHfRmPluWYXztg9gfC2cHpQw+Q/L2h12GSzFcfGy+ULwh5mJzNIXzCIbFR4e2xbCMwiq/NplXfXxdTECBFzHvbYrXde0LbXe5JdR9kzpMcaW5Vsd13ha1qA78jb56Nvf88TZerY/pksJysb6A3Sou/CB5WpzOm1qGSHt5yzsF
  • Ironport-sdr: iqVRJ4jo6Gtai/IuC6FdSoxdj5aLcvaGNrH+ushy3ZpdYs5MgOfAoePaa+2LZ+Hmyo3WSHU/Ab snwMrfQ1H9jA==
  • List-id: Mini-os development list <minios-devel.lists.xenproject.org>

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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.