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

[Minios-devel] [UNIKRAFT PATCH 6/8] lib/uksched: Add support for waiting threads


  • To: minios-devel@xxxxxxxxxxxxx
  • From: Costin Lupu <costin.lupu@xxxxxxxxx>
  • Date: Tue, 18 Sep 2018 18:27:27 +0300
  • Cc: felipe.huici@xxxxxxxxx, florian.schmidt@xxxxxxxxx, simon.kuenzer@xxxxxxxxx, yuri.volchkov@xxxxxxxxx
  • Delivery-date: Tue, 18 Sep 2018 15:27:43 +0000
  • Ironport-phdr: 9a23:lh/38hxZ2obU15/XCy+O+j09IxM/srCxBDY+r6Qd2uMSIJqq85mqBkHD//Il1AaPAd2Eraocw8Pt8InYEVQa5piAtH1QOLdtbDQizfssogo7HcSeAlf6JvO5JwYzHcBFSUM3tyrjaRsdF8nxfUDdrWOv5jAOBBr/KRB1JuPoEYLOksi7ze+/94HRbglSmDaxfa55IQmrownWqsQYm5ZpJLwryhvOrHtIeuBWyn1tKFmOgRvy5dq+8YB6/ShItP0v68BPUaPhf6QlVrNYFygpM3o05MLwqxbOSxaE62YGXWUXlhpIBBXF7A3/U5zsvCb2qvZx1S+HNsDwULs6Wymt771zRRHolikJKjA3/mLQhMNygqJWuw6tqwBlzoLIeoyZKOZyc6XAdt0aX2pBWcNRWjRfD4O7dIsPE+sBPeBFpIf7ulsOtQa+DhSrCezzzT9InWP23aw80+g7FQHGwRQgH88VvXvIt9X5Lr8SUf2uw6XS1zXDaOpb1DHg44bLahAsueyAUL1tfcbLykQiFxnJgkuOpYHnJT+Y2PwBv3WU4uZ9T+6iiG4qpxtvrjWhyMogkJTFi40Lxl3C6C532pw6JceiR05+edOkFZxQuDyEOIZuWcMiRn1ouD49yr0bpZ63ZCgKx4ojxx7Yc/GHbY2I7QjiVOaVOzt3mGlldKinhxav6kes0Pf8Vs6s3FZLqCpKjMXMu2gQ2xHc98SLUPhw80e71TqRyQze6PtILE4smareMZEhw7owlpQJsUTEGy/7gFn5jKiNdkU4++io7f7rYrH7pp+EKo95kR3xMr80lsynHOQ3KRICX3Kc+eikzr3s4VX5QKlWjv0xiqTZtZHaJcIapq6+GA9Zy5ss5AihDzi41NQVhn0HLFNeeBKblIjlIV7PL+7+DfulhFSsijhrzejcPrL9GpXNMmTDkLD5cLZz9UFczAszzchB6J5OCrEBPfPzVVPwtNHDCB82LRC7w+L9B9pmzI8RR3+PCLeDMKzOqV+I+v4vI+6UaY8bvDb9LOIl5//0gn8/g1MdZrWm3ZsSaHC5A/tmP16UYXzyjdgdFWcFpBExQPb0h12fSTRTfWq9X7og5jEnD4KrFZzDRoGogLyG2ie3BJ5WZn1YBVCKEHbnaZ+EVuwKaC2MPsBhliYLWqO7R4A/yBGkrBX6xKZ/LurI5i0Ysoru1dho5+3JlBE+7yJ0D8OZ026RT2F0nWQIRyEt0aB5v0Ny1lOD3rJjjPBCC9NT+qABbgBvMJ/azuthTtz/RA/FVtOIU0q9BMWrB3c2VN1i7cUJZhNWHM6+jxaL+zeyHvdBnLuQGJ0ytKbBx2XZLN0702vMkrMm2Qp1CvBTPHGr0/YsvzPYAJTExh2U
  • List-id: Mini-os development list <minios-devel.lists.xenproject.org>

Similar to waiting processes, we introduce support for waiting
threads. This is the conventional way of getting notified by
threads termination events and freeing the threads resources upon
exit.

A thread can be waited by other threads. If no such behaviour is
desired then one should set the detached attribute for the thread.
This implies that the thread resources will be automatically freed
when the thread exits.

Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx>
---
 lib/uksched/exportsyms.uk       |  3 +++
 lib/uksched/include/uk/thread.h |  6 +++++
 lib/uksched/thread.c            | 55 +++++++++++++++++++++++++++++++++++++++++
 lib/ukschedcoop/schedcoop.c     |  7 ++++++
 4 files changed, 71 insertions(+)

diff --git a/lib/uksched/exportsyms.uk b/lib/uksched/exportsyms.uk
index 951cd20..22c8913 100644
--- a/lib/uksched/exportsyms.uk
+++ b/lib/uksched/exportsyms.uk
@@ -14,6 +14,9 @@ uk_thread_fini
 uk_thread_block_timeout
 uk_thread_block
 uk_thread_wake
+uk_thread_exit
+uk_thread_wait
+uk_thread_detach
 uk_thread_set_prio
 uk_thread_get_prio
 uk_thread_set_timeslice
diff --git a/lib/uksched/include/uk/thread.h b/lib/uksched/include/uk/thread.h
index 7a1b630..3267ab2 100644
--- a/lib/uksched/include/uk/thread.h
+++ b/lib/uksched/include/uk/thread.h
@@ -36,6 +36,7 @@
 #include <uk/arch/time.h>
 #include <uk/plat/thread.h>
 #include <uk/thread_attr.h>
+#include <uk/wait_types.h>
 #include <uk/list.h>
 #include <uk/essentials.h>
 
@@ -52,6 +53,7 @@ struct uk_thread {
        UK_TAILQ_ENTRY(struct uk_thread) thread_list;
        uint32_t flags;
        __snsec wakeup_time;
+       struct uk_waitq waiting_threads;
        struct uk_sched *sched;
        void *sched_info;
 #ifdef CONFIG_HAVE_LIBC
@@ -68,6 +70,10 @@ UK_TAILQ_HEAD(uk_thread_list, struct uk_thread);
        uk_thread_create_attr(name, NULL, function, data)
 #define uk_thread_destroy(thread) \
        uk_sched_thread_destroy(thread->sched, thread)
+void uk_thread_exit(struct uk_thread *thread);
+
+int uk_thread_wait(struct uk_thread *thread);
+int uk_thread_detach(struct uk_thread *thread);
 
 int uk_thread_set_prio(struct uk_thread *thread, prio_t prio);
 int uk_thread_get_prio(const struct uk_thread *thread, prio_t *prio);
diff --git a/lib/uksched/thread.c b/lib/uksched/thread.c
index 3e69cfe..a06e338 100644
--- a/lib/uksched/thread.c
+++ b/lib/uksched/thread.c
@@ -36,6 +36,7 @@
 #include <uk/thread.h>
 #include <uk/_thread_info.h>
 #include <uk/sched.h>
+#include <uk/wait.h>
 #include <uk/print.h>
 #include <uk/assert.h>
 
@@ -87,6 +88,7 @@ int uk_thread_init(struct uk_thread *thread,
        /* Not runnable, not exited, not sleeping */
        thread->flags = 0;
        thread->wakeup_time = 0LL;
+       uk_waitq_init(&thread->waiting_threads);
        thread->sched_info = NULL;
 
 #ifdef CONFIG_HAVE_LIBC
@@ -132,6 +134,59 @@ void uk_thread_wake(struct uk_thread *thread)
        set_runnable(thread);
 }
 
+void uk_thread_exit(struct uk_thread *thread)
+{
+       struct thread_info_base *tib;
+
+       UK_ASSERT(thread);
+       UK_ASSERT(thread->sched);
+
+       set_exited(thread);
+
+       tib = thread->sched_info;
+
+       if (!tib->is_detached)
+               uk_waitq_wake_up(&thread->waiting_threads);
+
+       uk_printd(DLVL_EXTRA, "Thread \"%s\" exited.\n", thread->name);
+}
+
+int uk_thread_wait(struct uk_thread *thread)
+{
+       struct thread_info_base *tib;
+
+       UK_ASSERT(thread);
+       UK_ASSERT(thread->sched);
+
+       tib = thread->sched_info;
+
+       /* TODO critical region */
+
+       if (tib->is_detached)
+               return -1;
+
+       uk_waitq_wait_event(&thread->waiting_threads, is_exited(thread));
+
+       tib->is_detached = 1;
+
+       uk_sched_thread_destroy(thread->sched, thread);
+
+       return 0;
+}
+
+int uk_thread_detach(struct uk_thread *thread)
+{
+       struct thread_info_base *tib;
+
+       UK_ASSERT(thread);
+       UK_ASSERT(thread->sched);
+
+       tib = thread->sched_info;
+       tib->is_detached = 1;
+
+       return 0;
+}
+
 int uk_thread_set_prio(struct uk_thread *thread, prio_t prio)
 {
        if (!thread)
diff --git a/lib/ukschedcoop/schedcoop.c b/lib/ukschedcoop/schedcoop.c
index a2bf2ad..0a735bd 100644
--- a/lib/ukschedcoop/schedcoop.c
+++ b/lib/ukschedcoop/schedcoop.c
@@ -124,6 +124,12 @@ static void schedcoop_schedule(struct uk_sched *s)
                uk_sched_thread_switch(s, prev, next);
 
        UK_TAILQ_FOREACH_SAFE(thread, &s->exited_threads, thread_list, tmp) {
+               struct thread_info_base *tib = thread->sched_info;
+
+               if (!tib->is_detached)
+                       /* someone will eventually wait for it */
+                       continue;
+
                if (thread != prev)
                        uk_thread_destroy(thread);
        }
@@ -163,6 +169,7 @@ static void schedcoop_thread_remove(struct uk_sched *s, 
struct uk_thread *t)
 
        /* Put onto exited list */
        UK_TAILQ_INSERT_HEAD(&s->exited_threads, t, thread_list);
+       uk_thread_exit(t);
 
        ukplat_lcpu_restore_irqf(flags);
 
-- 
2.11.0


_______________________________________________
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®.