[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Minios-devel] [UNIKRAFT PATCH 4/5] lib/uklock: Introduce libuklock
On 14.06.2018 20:04, Sharan Santhanam wrote: We provide implementation for 2 type of synchronization primitives * Semaphore * Mutex Signed-off-by: Simon Kuenzer <simon.kuenzer@xxxxxxxxx> Signed-off-by: Sharan Santhanam <sharan.santhanam@xxxxxxxxx> --- lib/Config.uk | 1 + lib/Makefile.uk | 1 + lib/uklock/Config.uk | 22 ++++++ lib/uklock/Makefile.uk | 7 ++ lib/uklock/export.syms | 2 + lib/uklock/include/uk/mutex.h | 120 ++++++++++++++++++++++++++++++ lib/uklock/include/uk/semaphore.h | 153 ++++++++++++++++++++++++++++++++++++++ lib/uklock/mutex.c | 9 +++ lib/uklock/semaphore.c | 12 +++ 9 files changed, 327 insertions(+) create mode 100644 lib/uklock/Config.uk create mode 100644 lib/uklock/Makefile.uk create mode 100644 lib/uklock/export.syms create mode 100644 lib/uklock/include/uk/mutex.h create mode 100644 lib/uklock/include/uk/semaphore.h create mode 100644 lib/uklock/mutex.c create mode 100644 lib/uklock/semaphore.c diff --git a/lib/Config.uk b/lib/Config.uk index 0a78a02..9e6b269 100644 --- a/lib/Config.uk +++ b/lib/Config.uk @@ -33,4 +33,5 @@ source "lib/ukallocbbuddy/Config.uk" source "lib/uksched/Config.uk" source "lib/ukschedcoop/Config.uk" source "lib/fdt/Config.uk" +source "lib/uklock/Config.uk" source "lib/ukswrand/Config.uk" diff --git a/lib/Makefile.uk b/lib/Makefile.uk index d549152..a79ad0d 100644 --- a/lib/Makefile.uk +++ b/lib/Makefile.uk @@ -16,3 +16,4 @@ $(eval $(call _import_lib,$(CONFIG_UK_BASE)/lib/uksched)) $(eval $(call _import_lib,$(CONFIG_UK_BASE)/lib/ukschedcoop)) $(eval $(call _import_lib,$(CONFIG_UK_BASE)/lib/fdt)) $(eval $(call _import_lib,$(CONFIG_UK_BASE)/lib/vfscore)) +$(eval $(call _import_lib,$(CONFIG_UK_BASE)/lib/uklock)) diff --git a/lib/uklock/Config.uk b/lib/uklock/Config.uk new file mode 100644 index 0000000..984e348 --- /dev/null +++ b/lib/uklock/Config.uk @@ -0,0 +1,22 @@ +menuconfig LIBUKLOCK + bool "uklock: Multi-task synchronization primitives" + select LIBUKDEBUG + select LIBUKALLOC + select LIBUKSCHED + select LIBUKSEMAPHORE + select LIBUKMUTEX Why do we select here something that this library provides?I would rather prefer removing the config options underneath. If for instance someone does not use semaphores, our friend, the compiler, can remove these functions from the binary automatically. I think it is not necessary to provide configuration options for this library for now (maybe the same applies for LIBUKMPI). + default n + +if LIBUKLOCK + config LIBUKSEMAPHORE + bool "Semaphore" + default y + help + Enable semaphore based synchornization + + config LIBUKMUTEX + bool "Mutex" + default y + help + Enable mutex based synchornization +endif diff --git a/lib/uklock/Makefile.uk b/lib/uklock/Makefile.uk new file mode 100644 index 0000000..1b15524 --- /dev/null +++ b/lib/uklock/Makefile.uk @@ -0,0 +1,7 @@ +$(eval $(call addlib_s,libuklock,$(CONFIG_LIBUKLOCK))) + +CINCLUDES-$(CONFIG_LIBUKLOCK) += -I$(LIBUKLOCK_BASE)/include +CXXINCLUDES-$(CONFIG_LIBUKLOCK) += -I$(LIBUKLOCK_BASE)/include + +LIBUKLOCK_SRCS-$(CONFIG_LIBUKSEMAPHORE) += $(LIBUKLOCK_BASE)/semaphore.c +LIBUKLOCK_SRCS-$(CONFIG_LIBUKMUTEX) += $(LIBUKLOCK_BASE)/mutex.c diff --git a/lib/uklock/export.syms b/lib/uklock/export.syms new file mode 100644 index 0000000..bbb4d12 --- /dev/null +++ b/lib/uklock/export.syms @@ -0,0 +1,2 @@ +uk_semaphore_init +uk_mutex_init diff --git a/lib/uklock/include/uk/mutex.h b/lib/uklock/include/uk/mutex.h new file mode 100644 index 0000000..0a03a08 --- /dev/null +++ b/lib/uklock/include/uk/mutex.h @@ -0,0 +1,120 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Authors: Simon Kuenzer <simon.kuenzer@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_MUTEX_H__ +#define __UK_MUTEX_H__ + +#include <uk/config.h> +#if CONFIG_LIBUKMUTEX + +#include <uk/assert.h> +#include <uk/plat/lcpu.h> +#ifdef CONFIG_LIBUKSCHED +#include <uk/thread.h> +#include <uk/wait.h> +#include <uk/wait_types.h> +#include <uk/plat/time.h> +#endif /* CONFIG_LIBUKSCHED */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef CONFIG_LIBUKSCHED + +/* + * Mutex that relies on a scheduler + * uses wait queues for threads + */ +struct uk_mutex +{ + int locked; + struct uk_waitq wait; +}; + +void uk_mutex_init(struct uk_mutex *m); + +static inline void uk_mutex_hold(struct uk_mutex *m) +{ + unsigned long irqf; + + UK_ASSERT(m); + + for (;;) { + uk_waitq_wait_event(&m->wait, m->locked == 0); + irqf = ukplat_lcpu_save_irqf(); + if (!m->locked) + break; + ukplat_lcpu_restore_irqf(irqf); + } + m->locked = 1; + ukplat_lcpu_restore_irqf(irqf); +} + +static inline int uk_mutex_hold_try(struct uk_mutex *m) +{ + unsigned long irqf; + int ret = 0; + + UK_ASSERT(m); + + irqf = ukplat_lcpu_save_irqf(); + if (!m->locked) + ret = m->locked = 1; + ukplat_lcpu_restore_irqf(irqf); + return ret; +} + +static inline void uk_mutex_release(struct uk_mutex *m) +{ + unsigned long irqf; + + UK_ASSERT(m); + + irqf = ukplat_lcpu_save_irqf(); + UK_ASSERT(m->locked); + m->locked = 0; + uk_waitq_wake_up(&m->wait); + ukplat_lcpu_restore_irqf(irqf); +} + +#endif /* CONFIG_LIBUKSCHED */ + +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_LIBUKMUTEX */ + +#endif /* __UK_MUTEX_H__ */ diff --git a/lib/uklock/include/uk/semaphore.h b/lib/uklock/include/uk/semaphore.h new file mode 100644 index 0000000..d344e87 --- /dev/null +++ b/lib/uklock/include/uk/semaphore.h @@ -0,0 +1,153 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * 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. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR 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 AUTHOR 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. + */ +/* Taken and modified from Mini-OS (include/semphore.h) */ +#ifndef __UK_SEMAPHORE_H__ +#define __UK_SEMAPHORE_H__ + +#include <uk/config.h> + +#if CONFIG_LIBUKSEMAPHORE + +#include <uk/print.h> +#include <uk/assert.h> +#include <uk/plat/lcpu.h> +#if CONFIG_LIBUKSCHED +#include <uk/thread.h> +#include <uk/wait.h> +#include <uk/wait_types.h> +#include <uk/plat/time.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if CONFIG_LIBUKSCHED + +/* + * Semaphore that relies on a scheduler + * uses wait queues for threads + */ +struct uk_semaphore +{ + long count; + struct uk_waitq wait; +}; + +void uk_semaphore_init(struct uk_semaphore *s, long count); + +static inline void uk_semaphore_down(struct uk_semaphore *s) +{ + unsigned long irqf; + + UK_ASSERT(s); + + for (;;) { + uk_waitq_wait_event(&s->wait, s->count > 0); + irqf = ukplat_lcpu_save_irqf(); + if (s->count > 0) + break; + ukplat_lcpu_restore_irqf(irqf); + } + --s->count; + uk_printd(DLVL_INFO, "Decreased semaphore %p to %ld\n", s, s->count); + ukplat_lcpu_restore_irqf(irqf); +} + +static inline int uk_semaphore_down_try(struct uk_semaphore *s) +{ + unsigned long irqf; + int ret = 0; + + UK_ASSERT(s); + + irqf = ukplat_lcpu_save_irqf(); + if (s->count > 0) { + ret = 1; + --s->count; + uk_printd(DLVL_INFO, "Decreased semaphore %p to %ld\n", + s, s->count); + } + ukplat_lcpu_restore_irqf(irqf); + return ret; +} + +/* Returns __NSEC_MAX on timeout, expired time when down was successful */ +static inline __nsec uk_semaphore_down_to(struct uk_semaphore *s, + __nsec timeout) +{ + unsigned long irqf; + __nsec then = ukplat_monotonic_clock(); + __nsec deadline; + + UK_ASSERT(s); + + if (timeout == 0) + deadline = 0; + else + deadline = then + timeout; + + for (;;) { + uk_waitq_wait_event_deadline(&s->wait, s->count > 0, deadline); + irqf = ukplat_lcpu_save_irqf(); + if (s->count > 0 || (deadline && + ukplat_monotonic_clock() >= deadline)) + break; + ukplat_lcpu_restore_irqf(irqf); + } + if (s->count > 0) { + s->count--; + uk_printd(DLVL_INFO, "Decreased semaphore %p to %ld\n", + s, s->count); + ukplat_lcpu_restore_irqf(irqf); + return ukplat_monotonic_clock() - then; + } + + ukplat_lcpu_restore_irqf(irqf); + uk_printd(DLVL_INFO, "Timed out while waiting for semaphore %p\n", s); + return __NSEC_MAX; +} + +static inline void uk_semaphore_up(struct uk_semaphore *s) +{ + unsigned long irqf; + + UK_ASSERT(s); + + irqf = ukplat_lcpu_save_irqf(); + ++s->count; + uk_printd(DLVL_INFO, "Increased semaphore %p to %ld\n", + s, s->count); + uk_waitq_wake_up(&s->wait); + ukplat_lcpu_restore_irqf(irqf); +} +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_LIBUKSEMAPHORE */ + +#endif /* __UK_SEMAPHORE_H__ */ diff --git a/lib/uklock/mutex.c b/lib/uklock/mutex.c new file mode 100644 index 0000000..be7413f --- /dev/null +++ b/lib/uklock/mutex.c @@ -0,0 +1,9 @@ +#include <uk/mutex.h> + +#ifdef CONFIG_LIBUKSCHED +void uk_mutex_init(struct uk_mutex *m) +{ + m->locked = 0; + uk_waitq_init(&m->wait); +} +#endif /* CONFIG_LIBUKSCHED */ diff --git a/lib/uklock/semaphore.c b/lib/uklock/semaphore.c new file mode 100644 index 0000000..aa084ea --- /dev/null +++ b/lib/uklock/semaphore.c @@ -0,0 +1,12 @@ +#include <uk/semaphore.h> + +#ifdef CONFIG_LIBUKSCHED +void uk_semaphore_init(struct uk_semaphore *s, long count) +{ + s->count = count; + uk_waitq_init(&s->wait); + + uk_printd(DLVL_INFO, "Initialized semaphore %p with %ld\n", + s, s->count); +} +#endif /* CONFIG_LIBUKSCHED */ _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |