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

[Minios-devel] [UNIKRAFT PATCH v4 05/12] lib/uksched: Add support for waiting threads


  • To: minios-devel@xxxxxxxxxxxxx
  • From: Costin Lupu <costin.lupu@xxxxxxxxx>
  • Date: Fri, 22 Mar 2019 16:16:32 +0200
  • Cc: Florian.Schmidt@xxxxxxxxx
  • Delivery-date: Fri, 22 Mar 2019 14:16:49 +0000
  • Ironport-phdr: 9a23:t9CFIxUQg4bkFkoJatMDGb59SwLV8LGtZVwlr6E/grcLSJyIuqrYbBWOt8tkgFKBZ4jH8fUM07OQ7/m4HzNZqsve+Fk5M7V0HycfjssXmwFySOWkMmbcaMDQUiohAc5ZX0Vk9XzoeWJcGcL5ekGA6ibqtW1aFRrwLxd6KfroEYDOkcu3y/qy+5rOaAlUmTaxe7x/IAiqoQnLtMQanIRuJ6YzxxDUvnZGZuNayH9yK1mOhRj8/MCw/JBi8yRUpf0s8tNLXLv5caolU7FWFSwqPG8p6sLlsxnDVhaP6WAHUmoKiBpIAhPK4w/8U5zsryb1rOt92C2dPc3rUbA5XCmp4ql3RBP0jioMKjg0+3zVhMNtlqJWuBKvqQJizYDaY4+bM/hxfq3GcN8GWWZMRNpdWjZdDo+gaYYEEuoPPfxfr4n4v1YDsxy+BRKwBOPuzD9Dm3n43bAi0+Q8DArL2xAvH9UVsHTIrdX1Mr0eUeSozKnQ0DXOdO9Z2Szn5IjQbxAuuuuAXah3ccfIz0QkCgDLjk2IpID4MD6Zy/4Bvmub4uZ6S+6jlWwqpxt/rzS328shhZTFipgWx13E7yl13og4KNOiREJmbtOoDp1dvDyAOYRsWMMtWWRotT4/yr0BpJG0YjAHyI8ixx7Dc/yHdJWI4g77WOaRPzh4gHVldaqhhxa360egy+n8WtOo31ZRtCZFisTMuWsX2xzJ7ciLUvp9/kG/1jaTzw3f9+5JLV0umafYK5Mt2KA8moQRvEjZECL6gED2g7WXdkUg9Oio8ePnYrD+q5CAMI90kR3+MqUomsClBeQ4LxAOX3WA9Ougz73v51X5QKhRgfEsiKnZt4jWJd4Hqa6hHw9VzoEj5g66Dzen1tQYnH4HLElcdB2akYfpJU/BIPTjAPe7glSsiytrx+vcMrzuHJrNKGLPkLD7fbZy80Rc0hY8zchD55JIDbEMOPL9Wkv2tNzCDx82KQq0z/z6Btph1oMeXGOPDbKFMK7Jt1+H+P4gI+2Wa4AOojryNeUltLbSiio8mFkcerLs0ZYJZXSQGvV9P17fcXfqxNAbHjQkpA07Gcftk0GDV3Z3em6vF/Y34SonCYTgCZrbW6imm/qZwS39BJoANTMOMUyFDXq9L9bMYPwLci/HesI=
  • Ironport-sdr: Ej11K6NSMdNcxZfsEW2AF7rvL/1aHZDMQg8vr8bFVunlkuh642KM61BGjGLXQ1MOKhOrFkXinu nMYanID4rGYQ==
  • 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 thread
termination events and freeing thread resources upon exit.

A thread can be waited on 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>
Reviewed-by: Florian Schmidt <florian.schmidt@xxxxxxxxx>
---
 lib/uksched/exportsyms.uk       |  2 ++
 lib/uksched/include/uk/thread.h | 10 ++++++++++
 lib/uksched/thread.c            | 32 ++++++++++++++++++++++++++++++++
 lib/ukschedcoop/schedcoop.c     |  6 ++++++
 4 files changed, 50 insertions(+)

diff --git a/lib/uksched/exportsyms.uk b/lib/uksched/exportsyms.uk
index 334c652f..3118383d 100644
--- a/lib/uksched/exportsyms.uk
+++ b/lib/uksched/exportsyms.uk
@@ -11,6 +11,8 @@ uk_sched_thread_sleep
 uk_sched_thread_exit
 uk_thread_init
 uk_thread_fini
+uk_thread_exit
+uk_thread_wait
 uk_thread_detach
 uk_thread_set_prio
 uk_thread_get_prio
diff --git a/lib/uksched/include/uk/thread.h b/lib/uksched/include/uk/thread.h
index 5f3c2501..131268b4 100644
--- a/lib/uksched/include/uk/thread.h
+++ b/lib/uksched/include/uk/thread.h
@@ -37,6 +37,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>
 
@@ -54,6 +55,7 @@ struct uk_thread {
        uint32_t flags;
        __snsec wakeup_time;
        bool detached;
+       struct uk_waitq waiting_threads;
        struct uk_sched *sched;
 #ifdef CONFIG_HAVE_LIBC
        struct _reent reent;
@@ -69,6 +71,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);
@@ -88,11 +94,15 @@ struct uk_thread *uk_thread_current(void)
 }
 
 #define RUNNABLE_FLAG   0x00000001
+#define EXITED_FLAG     0x00000002
 
 #define is_runnable(_thread)    ((_thread)->flags &   RUNNABLE_FLAG)
 #define set_runnable(_thread)   ((_thread)->flags |=  RUNNABLE_FLAG)
 #define clear_runnable(_thread) ((_thread)->flags &= ~RUNNABLE_FLAG)
 
+#define is_exited(_thread)      ((_thread)->flags &   EXITED_FLAG)
+#define set_exited(_thread)     ((_thread)->flags |=  EXITED_FLAG)
+
 int uk_thread_init(struct uk_thread *thread,
                struct ukplat_ctx_callbacks *cbs, struct uk_alloc *allocator,
                const char *name, void *stack,
diff --git a/lib/uksched/thread.c b/lib/uksched/thread.c
index aeeaff17..ff0fb39f 100644
--- a/lib/uksched/thread.c
+++ b/lib/uksched/thread.c
@@ -35,6 +35,7 @@
 #include <uk/plat/time.h>
 #include <uk/thread.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,
        thread->flags = 0;
        thread->wakeup_time = 0LL;
        thread->detached = false;
+       uk_waitq_init(&thread->waiting_threads);
 
 #ifdef CONFIG_HAVE_LIBC
        //TODO _REENT_INIT_PTR(&thread->reent);
@@ -131,6 +133,36 @@ void uk_thread_wake(struct uk_thread *thread)
        set_runnable(thread);
 }
 
+void uk_thread_exit(struct uk_thread *thread)
+{
+       UK_ASSERT(thread);
+
+       set_exited(thread);
+
+       if (!thread->detached)
+               uk_waitq_wake_up(&thread->waiting_threads);
+
+       uk_pr_debug("Thread \"%s\" exited.\n", thread->name);
+}
+
+int uk_thread_wait(struct uk_thread *thread)
+{
+       UK_ASSERT(thread);
+
+       /* TODO critical region */
+
+       if (thread->detached)
+               return -EINVAL;
+
+       uk_waitq_wait_event(&thread->waiting_threads, is_exited(thread));
+
+       thread->detached = true;
+
+       uk_sched_thread_destroy(thread->sched, thread);
+
+       return 0;
+}
+
 int uk_thread_detach(struct uk_thread *thread)
 {
        UK_ASSERT(thread);
diff --git a/lib/ukschedcoop/schedcoop.c b/lib/ukschedcoop/schedcoop.c
index 6f46d49e..5091c913 100644
--- a/lib/ukschedcoop/schedcoop.c
+++ b/lib/ukschedcoop/schedcoop.c
@@ -124,6 +124,10 @@ static void schedcoop_schedule(struct uk_sched *s)
                uk_sched_thread_switch(s, prev, next);
 
        UK_TAILQ_FOREACH_SAFE(thread, &prv->exited_threads, thread_list, tmp) {
+               if (!thread->detached)
+                       /* someone will eventually wait for it */
+                       continue;
+
                if (thread != prev) {
                        UK_TAILQ_REMOVE(&prv->exited_threads,
                                        thread, thread_list);
@@ -156,6 +160,8 @@ static void schedcoop_thread_remove(struct uk_sched *s, 
struct uk_thread *t)
        UK_TAILQ_REMOVE(&prv->thread_list, t, thread_list);
        clear_runnable(t);
 
+       uk_thread_exit(t);
+
        /* Put onto exited list */
        UK_TAILQ_INSERT_HEAD(&prv->exited_threads, t, thread_list);
 
-- 
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®.