[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH 4/5] lib/uklock: Introduce libuklock
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 + 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 */ -- 2.7.4 _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |