|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Minios-devel] [UNIKRAFT PATCH 3/8] lib/uksched: Introduce thread attributes
Hi Costin,
Please see a few comments inline.
On 9/18/18, 5:27 PM, "Costin Lupu" <costin.lupu@xxxxxxxxx> wrote:
>We introduce thread attributes abstraction which is used for
>configuring thread behaviors. The set of currently available
>attributes was inspired from the pthread interface.
s/thread attributes/a thread attributes
s/thread behaviors/thread behavior.
>Thread attributes can be set either when creating the threads or
>during threads execution by calling the corresponding setters. If
>an attribute is not supported by the underlying scheduler then
>-EINVAL is returned by setters.
s/or during threads/or during thread
>The detach attribute is common to all threads, regardless the
>scheduling policy, and if set it means that the thread resources
>will be automatically freed on thread exit. By default, threads
>are not detached. The complete detach support will be added in a
>following commit.
s/regardless/regardless of
>Time slice and priority make sense only for preemptive schedulers.
>
>Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx>
>---
> lib/uksched/Makefile.uk | 1 +
> lib/uksched/exportsyms.uk | 12 +++
> lib/uksched/include/uk/sched.h | 75 +++++++++++++++++--
> lib/uksched/include/uk/thread.h | 12 ++-
> lib/uksched/include/uk/thread_attr.h | 73 +++++++++++++++++++
> lib/uksched/sched.c | 5 +-
> lib/uksched/thread.c | 34 +++++++++
> lib/uksched/thread_attr.c | 137
>+++++++++++++++++++++++++++++++++++
> lib/ukschedcoop/schedcoop.c | 6 +-
> 9 files changed, 345 insertions(+), 10 deletions(-)
> create mode 100644 lib/uksched/include/uk/thread_attr.h
> create mode 100644 lib/uksched/thread_attr.c
>
>diff --git a/lib/uksched/Makefile.uk b/lib/uksched/Makefile.uk
>index 24816f6..229d847 100644
>--- a/lib/uksched/Makefile.uk
>+++ b/lib/uksched/Makefile.uk
>@@ -5,3 +5,4 @@ CXXINCLUDES-$(CONFIG_LIBUKSCHED) +=
>-I$(LIBUKSCHED_BASE)/include
>
> LIBUKSCHED_SRCS-y += $(LIBUKSCHED_BASE)/sched.c
> LIBUKSCHED_SRCS-y += $(LIBUKSCHED_BASE)/thread.c
>+LIBUKSCHED_SRCS-y += $(LIBUKSCHED_BASE)/thread_attr.c
>diff --git a/lib/uksched/exportsyms.uk b/lib/uksched/exportsyms.uk
>index 45a9694..7d8e102 100644
>--- a/lib/uksched/exportsyms.uk
>+++ b/lib/uksched/exportsyms.uk
>@@ -14,3 +14,15 @@ uk_thread_fini
> uk_thread_block_timeout
> uk_thread_block
> uk_thread_wake
>+uk_thread_set_prio
>+uk_thread_get_prio
>+uk_thread_set_timeslice
>+uk_thread_get_timeslice
>+uk_thread_attr_init
>+uk_thread_attr_fini
>+uk_thread_attr_set_detachstate
>+uk_thread_attr_get_detachstate
>+uk_thread_attr_set_prio
>+uk_thread_attr_get_prio
>+uk_thread_attr_set_timeslice
>+uk_thread_attr_get_timeslice
>diff --git a/lib/uksched/include/uk/sched.h
>b/lib/uksched/include/uk/sched.h
>index d2fc8df..b21d65c 100644
>--- a/lib/uksched/include/uk/sched.h
>+++ b/lib/uksched/include/uk/sched.h
>@@ -60,16 +60,31 @@ typedef void (*uk_sched_yield_func_t)
> (struct uk_sched *s);
>
> typedef void (*uk_sched_thread_add_func_t)
>- (struct uk_sched *s, struct uk_thread *t);
>+ (struct uk_sched *s, struct uk_thread *t,
>+ struct uk_thread_attr *attr);
> typedef void (*uk_sched_thread_remove_func_t)
> (struct uk_sched *s, struct uk_thread *t);
>
>+typedef int (*uk_sched_thread_set_prio_func_t)
>+ (struct uk_sched *s, struct uk_thread *t, prio_t prio);
>+typedef int (*uk_sched_thread_get_prio_func_t)
>+ (struct uk_sched *s, const struct uk_thread *t, prio_t *prio);
>+typedef int (*uk_sched_thread_set_tslice_func_t)
>+ (struct uk_sched *s, struct uk_thread *t, int tslice);
>+typedef int (*uk_sched_thread_get_tslice_func_t)
>+ (struct uk_sched *s, const struct uk_thread *t, int *tslice);
>+
> struct uk_sched {
> uk_sched_yield_func_t yield;
>
> uk_sched_thread_add_func_t thread_add;
> uk_sched_thread_remove_func_t thread_remove;
>
>+ uk_sched_thread_set_prio_func_t thread_set_prio;
>+ uk_sched_thread_get_prio_func_t thread_get_prio;
>+ uk_sched_thread_set_tslice_func_t thread_set_tslice;
>+ uk_sched_thread_get_tslice_func_t thread_get_tslice;
>+
> /* internal */
> struct uk_thread idle;
> struct ukplat_ctx_callbacks plat_ctx_cbs;
>@@ -92,12 +107,12 @@ static inline void uk_sched_yield(void)
> }
>
> static inline void uk_sched_thread_add(struct uk_sched *s,
>- struct uk_thread *t)
>+ struct uk_thread *t, struct uk_thread_attr *attr)
> {
> UK_ASSERT(s);
> UK_ASSERT(t);
> t->sched = s;
>- s->thread_add(s, t);
>+ s->thread_add(s, t, attr);
> }
>
> static inline void uk_sched_thread_remove(struct uk_sched *s,
>@@ -109,6 +124,49 @@ static inline void uk_sched_thread_remove(struct
>uk_sched *s,
> t->sched = NULL;
> }
>
>+static inline int uk_sched_thread_set_prio(struct uk_sched *s,
>+ struct uk_thread *t, prio_t prio)
>+{
>+ UK_ASSERT(s);
>+
>+ if (!s->thread_set_prio)
>+ return -EINVAL;
>+
>+ return s->thread_set_prio(s, t, prio);
>+}
>+
>+static inline int uk_sched_thread_get_prio(struct uk_sched *s,
>+ const struct uk_thread *t, prio_t *prio)
>+{
>+ UK_ASSERT(s);
>+
>+ if (!s->thread_get_prio)
>+ return -EINVAL;
>+
>+ return s->thread_get_prio(s, t, prio);
>+}
>+
>+static inline int uk_sched_thread_set_timeslice(struct uk_sched *s,
>+ struct uk_thread *t, int tslice)
>+{
>+ UK_ASSERT(s);
>+
>+ if (!s->thread_set_tslice)
>+ return -EINVAL;
>+
>+ return s->thread_set_tslice(s, t, tslice);
>+}
>+
>+static inline int uk_sched_thread_get_timeslice(struct uk_sched *s,
>+ const struct uk_thread *t, int *tslice)
>+{
>+ UK_ASSERT(s);
>+
>+ if (!s->thread_get_tslice)
>+ return -EINVAL;
>+
>+ return s->thread_get_tslice(s, t, tslice);
>+}
>
> /*
> * Internal scheduler functions
>@@ -132,11 +190,17 @@ static inline struct uk_thread
>*uk_sched_get_idle(struct uk_sched *s)
> void uk_sched_start(struct uk_sched *sched) __noreturn;
>
> #define uk_sched_init(s, yield_func, \
>- thread_add_func, thread_remove_func) \
>+ thread_add_func, thread_remove_func, \
>+ thread_set_prio_func, thread_get_prio_func, \
>+ thread_set_tslice_func, thread_get_tslice_func) \
> do { \
> (s)->yield = yield_func; \
> (s)->thread_add = thread_add_func; \
> (s)->thread_remove = thread_remove_func; \
>+ (s)->thread_set_prio = thread_set_prio_func; \
>+ (s)->thread_get_prio = thread_get_prio_func; \
>+ (s)->thread_set_tslice = thread_set_tslice_func; \
>+ (s)->thread_get_tslice = thread_get_tslice_func; \
> uk_sched_register((s)); \
> } while (0)
>
>@@ -146,7 +210,8 @@ void uk_sched_start(struct uk_sched *sched)
>__noreturn;
> */
>
> struct uk_thread *uk_sched_thread_create(struct uk_sched *sched,
>- const char *name, void (*function)(void *), void *arg);
>+ const char *name, struct uk_thread_attr *attr,
>+ void (*function)(void *), void *arg);
> void uk_sched_thread_destroy(struct uk_sched *sched,
> struct uk_thread *thread);
>
>diff --git a/lib/uksched/include/uk/thread.h
>b/lib/uksched/include/uk/thread.h
>index e66a05b..5ff2dd6 100644
>--- a/lib/uksched/include/uk/thread.h
>+++ b/lib/uksched/include/uk/thread.h
>@@ -35,6 +35,7 @@
> #include <uk/arch/lcpu.h>
> #include <uk/arch/time.h>
> #include <uk/plat/thread.h>
>+#include <uk/thread_attr.h>
> #include <uk/list.h>
> #include <uk/essentials.h>
>
>@@ -59,11 +60,20 @@ struct uk_thread {
>
> UK_TAILQ_HEAD(uk_thread_list, struct uk_thread);
>
>+#define uk_thread_create_attr(name, attr, function, data) \
>+ uk_sched_thread_create(uk_sched_get_default(), \
>+ name, attr, function, data)
> #define uk_thread_create(name, function, data) \
>- uk_sched_thread_create(uk_sched_get_default(), name, function, data)
>+ uk_thread_create_attr(name, NULL, function, data)
> #define uk_thread_destroy(thread) \
> uk_sched_thread_destroy(thread->sched, 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);
>+
>+int uk_thread_set_timeslice(struct uk_thread *thread, int timeslice);
>+int uk_thread_get_timeslice(const struct uk_thread *thread, int
>*timeslice);
>+
> static inline
> struct uk_thread *uk_thread_current(void)
> {
>diff --git a/lib/uksched/include/uk/thread_attr.h
>b/lib/uksched/include/uk/thread_attr.h
>new file mode 100644
>index 0000000..30be708
>--- /dev/null
>+++ b/lib/uksched/include/uk/thread_attr.h
>@@ -0,0 +1,73 @@
>+/* SPDX-License-Identifier: BSD-3-Clause */
>+/*
>+ * Authors: Costin Lupu <costin.lupu@xxxxxxxxx>
>+ *
>+ * Copyright (c) 2018, NEC Europe Ltd., NEC Corporation. All rights
>reserved.
>+ *
>+ * Redistribution and use in source and binary forms, with or without
>+ * modification, are permitted provided that the following conditions
>+ * are met:
>+ *
>+ * 1. Redistributions of source code must retain the above copyright
>+ * notice, this list of conditions and the following disclaimer.
>+ * 2. Redistributions in binary form must reproduce the above copyright
>+ * notice, this list of conditions and the following disclaimer in the
>+ * documentation and/or other materials provided with the
>distribution.
>+ * 3. Neither the name of the copyright holder nor the names of its
>+ * contributors may be used to endorse or promote products derived
>from
>+ * this software without specific prior written permission.
>+ *
>+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>"AS IS"
>+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
>THE
>+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
>PURPOSE
>+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
>CONTRIBUTORS BE
>+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
>+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
>+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
>BUSINESS
>+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
>IN
>+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
>OTHERWISE)
>+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
>OF THE
>+ * POSSIBILITY OF SUCH DAMAGE.
>+ *
>+ * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
>+ */
>+
>+#ifndef __UK_SCHED_THREAD_ATTR_H__
>+#define __UK_SCHED_THREAD_ATTR_H__
>+
>+#ifdef __cplusplus
>+extern "C" {
>+#endif
>+
>+#define UK_THREAD_ATTR_WAITABLE 0
>+#define UK_THREAD_ATTR_DETACHED 1
>+
>+#define UK_THREAD_ATTR_PRIO_MIN 0
>+#define UK_THREAD_ATTR_PRIO_MAX 255
>+#define UK_THREAD_ATTR_PRIO_DEFAULT 127
>+
>+typedef int prio_t;
>+
>+typedef struct uk_thread_attr {
>+ int is_detached;
>+ prio_t prio;
>+ int timeslice;
>+} uk_thread_attr_t;
>+
>+int uk_thread_attr_init(uk_thread_attr_t *attr);
>+int uk_thread_attr_fini(uk_thread_attr_t *attr);
>+
>+int uk_thread_attr_set_detachstate(uk_thread_attr_t *attr, int state);
>+int uk_thread_attr_get_detachstate(const uk_thread_attr_t *attr, int
>*state);
>+
>+int uk_thread_attr_set_prio(uk_thread_attr_t *attr, prio_t prio);
>+int uk_thread_attr_get_prio(const uk_thread_attr_t *attr, prio_t *prio);
>+
>+int uk_thread_attr_set_timeslice(uk_thread_attr_t *attr, int timeslice);
>+int uk_thread_attr_get_timeslice(const uk_thread_attr_t *attr, int
>*timeslice);
>+
>+#ifdef __cplusplus
>+}
>+#endif
>+
>+#endif /* __UK_SCHED_THREAD_ATTR_H__ */
>diff --git a/lib/uksched/sched.c b/lib/uksched/sched.c
>index 8276e15..f2eca33 100644
>--- a/lib/uksched/sched.c
>+++ b/lib/uksched/sched.c
>@@ -170,7 +170,8 @@ void uk_sched_idle_init(struct uk_sched *sched,
> }
>
> struct uk_thread *uk_sched_thread_create(struct uk_sched *sched,
>- const char *name, void (*function)(void *), void *arg)
>+ const char *name, struct uk_thread_attr *attr,
>+ void (*function)(void *), void *arg)
> {
> struct uk_thread *thread = NULL;
> void *stack = NULL;
>@@ -195,7 +196,7 @@ struct uk_thread *uk_sched_thread_create(struct
>uk_sched *sched,
> if (rc)
> goto err;
>
>- uk_sched_thread_add(sched, thread);
>+ uk_sched_thread_add(sched, thread, attr);
>
> return thread;
>
>diff --git a/lib/uksched/thread.c b/lib/uksched/thread.c
>index 4b00b1a..a6d90fc 100644
>--- a/lib/uksched/thread.c
>+++ b/lib/uksched/thread.c
>@@ -30,9 +30,11 @@
> * Ported from Mini-OS
> */
> #include <stdlib.h>
>+#include <errno.h>
> #include <uk/plat/config.h>
> #include <uk/plat/time.h>
> #include <uk/thread.h>
>+#include <uk/sched.h>
> #include <uk/print.h>
> #include <uk/assert.h>
>
>@@ -127,3 +129,35 @@ void uk_thread_wake(struct uk_thread *thread)
> thread->wakeup_time = 0LL;
> set_runnable(thread);
> }
>+
>+int uk_thread_set_prio(struct uk_thread *thread, prio_t prio)
>+{
>+ if (!thread)
>+ return -EINVAL;
>+
>+ return uk_sched_thread_set_prio(thread->sched, thread, prio);
>+}
>+
>+int uk_thread_get_prio(const struct uk_thread *thread, prio_t *prio)
>+{
>+ if (!thread)
>+ return -EINVAL;
>+
>+ return uk_sched_thread_get_prio(thread->sched, thread, prio);
>+}
>+
>+int uk_thread_set_timeslice(struct uk_thread *thread, int timeslice)
>+{
>+ if (!thread)
>+ return -EINVAL;
>+
>+ return uk_sched_thread_set_timeslice(thread->sched, thread, timeslice);
>+}
>+
>+int uk_thread_get_timeslice(const struct uk_thread *thread, int
>*timeslice)
>+{
>+ if (!thread)
>+ return -EINVAL;
>+
>+ return uk_sched_thread_get_timeslice(thread->sched, thread, timeslice);
>+}
>diff --git a/lib/uksched/thread_attr.c b/lib/uksched/thread_attr.c
>new file mode 100644
>index 0000000..cff1a55
>--- /dev/null
>+++ b/lib/uksched/thread_attr.c
>@@ -0,0 +1,137 @@
>+/* SPDX-License-Identifier: BSD-3-Clause */
>+/*
>+ * Authors: Costin Lupu <costin.lupu@xxxxxxxxx>
>+ *
>+ * Copyright (c) 2018, NEC Europe Ltd., NEC Corporation. All rights
>reserved.
>+ *
>+ * Redistribution and use in source and binary forms, with or without
>+ * modification, are permitted provided that the following conditions
>+ * are met:
>+ *
>+ * 1. Redistributions of source code must retain the above copyright
>+ * notice, this list of conditions and the following disclaimer.
>+ * 2. Redistributions in binary form must reproduce the above copyright
>+ * notice, this list of conditions and the following disclaimer in the
>+ * documentation and/or other materials provided with the
>distribution.
>+ * 3. Neither the name of the copyright holder nor the names of its
>+ * contributors may be used to endorse or promote products derived
>from
>+ * this software without specific prior written permission.
>+ *
>+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>"AS IS"
>+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
>THE
>+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
>PURPOSE
>+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
>CONTRIBUTORS BE
>+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
>+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
>+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
>BUSINESS
>+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
>IN
>+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
>OTHERWISE)
>+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
>OF THE
>+ * POSSIBILITY OF SUCH DAMAGE.
>+ *
>+ * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
>+ */
>+
>+#include <stdlib.h>
>+#include <errno.h>
>+#include <uk/plat/time.h>
>+#include <uk/thread_attr.h>
>+#include <uk/assert.h>
>+
>+
>+int uk_thread_attr_init(uk_thread_attr_t *attr)
>+{
>+ if (attr == NULL)
>+ return EINVAL;
>+
>+ attr->is_detached = 0;
>+ attr->prio = -1;
>+ attr->timeslice = 0;
>+
>+ return 0;
>+}
Minor: perhaps define some macros for the 0s and -1s you have here. Also,
return -EINVAL instead of EINVAL.
Same for all uk_thread_attr_* functions below.
>+
>+int uk_thread_attr_fini(uk_thread_attr_t *attr)
>+{
>+ if (attr == NULL)
>+ return EINVAL;
>+
>+ return 0;
>+}
>+
>+int uk_thread_attr_set_detachstate(uk_thread_attr_t *attr, int state)
>+{
>+ if (attr == NULL)
>+ return EINVAL;
>+
>+ if (state == UK_THREAD_ATTR_DETACHED)
>+ attr->is_detached = 1;
>+
>+ else if (state == UK_THREAD_ATTR_WAITABLE)
>+ attr->is_detached = 0;
>+
>+ else
>+ return EINVAL;
>+
>+ return 0;
>+}
Shouldn’t you be setting attr’s members to macros, i.e., attr->is_detached
= UK_THREAD_ATTR_DETACHED ?
>+
>+int uk_thread_attr_get_detachstate(const uk_thread_attr_t *attr, int
>*state)
>+{
>+ if (attr == NULL || state == NULL)
>+ return EINVAL;
>+
>+ if (attr->is_detached)
>+ *state = UK_THREAD_ATTR_DETACHED;
>+ else
>+ *state = UK_THREAD_ATTR_WAITABLE;
>+
>+ return 0;
>+}
>+
>+int uk_thread_attr_set_prio(uk_thread_attr_t *attr, prio_t prio)
>+{
>+ int rc = EINVAL;
>+
>+ if (attr == NULL)
>+ return rc;
>+
>+ if (prio >= UK_THREAD_ATTR_PRIO_MIN &&
>+ prio <= UK_THREAD_ATTR_PRIO_MAX) {
>+ attr->prio = prio;
>+ rc = 0;
>+ }
>+
>+ return rc;
>+}
>+
>+int uk_thread_attr_get_prio(const uk_thread_attr_t *attr, prio_t *prio)
>+{
>+ if (attr == NULL || prio == NULL)
>+ return EINVAL;
>+
>+ *prio = attr->prio;
>+
>+ return 0;
>+}
>+
>+int uk_thread_attr_set_timeslice(uk_thread_attr_t *attr, int timeslice)
>+{
>+ if (attr == NULL)
>+ return EINVAL;
>+
>+ /* TODO check timeslice agains platform tick */
>+ attr->timeslice = timeslice;
>+
>+ return 0;
>+}
s/agains/against. Also, when will this be implemented?
Thanks,
— Felipe
>+
>+int uk_thread_attr_get_timeslice(const uk_thread_attr_t *attr, int
>*timeslice)
>+{
>+ if (attr == NULL || timeslice == NULL)
>+ return EINVAL;
>+
>+ *timeslice = attr->timeslice;
>+
>+ return 0;
>+}
>diff --git a/lib/ukschedcoop/schedcoop.c b/lib/ukschedcoop/schedcoop.c
>index d78ca54..bc02d08 100644
>--- a/lib/ukschedcoop/schedcoop.c
>+++ b/lib/ukschedcoop/schedcoop.c
>@@ -132,7 +132,8 @@ static void schedcoop_schedule(struct uk_sched *s)
> }
> }
>
>-static void schedcoop_thread_add(struct uk_sched *s, struct uk_thread *t)
>+static void schedcoop_thread_add(struct uk_sched *s, struct uk_thread *t,
>+ struct uk_thread_attr *attr __unused)
> {
> unsigned long flags;
> struct schedcoop_private *prv = s->prv;
>@@ -210,7 +211,8 @@ struct uk_sched *uk_schedcoop_init(struct uk_alloc *a)
> uk_sched_init(sched,
> schedcoop_yield,
> schedcoop_thread_add,
>- schedcoop_thread_remove);
>+ schedcoop_thread_remove,
>+ NULL, NULL, NULL, NULL);
>
> return sched;
> }
>--
>2.11.0
>
_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |