[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Minios-devel] [UNIKRAFT PATCH v3 2/3] lib/uklock: Introduce semaphores and mutexes with libuklock
Reviewed-by: Yuri Volchkov <yuri.volchkov@xxxxxxxxx> Simon Kuenzer <simon.kuenzer@xxxxxxxxx> writes: > From: Sharan Santhanam <sharan.santhanam@xxxxxxxxx> > > Provides implementation for 2 types of synchronization primitives: > * Semaphore > * Mutex > They are based on libuksched because they are using thread waiting > queues. > > 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 | 20 ++++++ > lib/uklock/Makefile.uk | 7 ++ > lib/uklock/export.syms | 2 + > lib/uklock/include/uk/mutex.h | 113 +++++++++++++++++++++++++++++ > lib/uklock/include/uk/semaphore.h | 146 > ++++++++++++++++++++++++++++++++++++++ > lib/uklock/mutex.c | 7 ++ > lib/uklock/semaphore.c | 10 +++ > 9 files changed, 307 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..5ce22c9 > --- /dev/null > +++ b/lib/uklock/Config.uk > @@ -0,0 +1,20 @@ > +menuconfig LIBUKLOCK > + bool "uklock: Multi-task synchronization primitives" > + select LIBUKDEBUG > + default n > + > +if LIBUKLOCK > + config LIBUKLOCK_SEMAPHORE > + bool "Semaphores" > + select LIBUKSCHED > + default y > + help > + Enable semaphore based synchornization > + > + config LIBUKLOCK_MUTEX > + bool "Mutexes" > + select LIBUKSCHED > + 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..396adee > --- /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_LIBUKLOCK_SEMAPHORE) += $(LIBUKLOCK_BASE)/semaphore.c > +LIBUKLOCK_SRCS-$(CONFIG_LIBUKLOCK_MUTEX) += $(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..7b0208a > --- /dev/null > +++ b/lib/uklock/include/uk/mutex.h > @@ -0,0 +1,113 @@ > +/* 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_LIBUKLOCK_MUTEX > +#include <uk/assert.h> > +#include <uk/plat/lcpu.h> > +#include <uk/thread.h> > +#include <uk/wait.h> > +#include <uk/wait_types.h> > +#include <uk/plat/time.h> > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +/* > + * 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); > +} > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* CONFIG_LIBUKLOCK_MUTEX */ > + > +#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..fd181c8 > --- /dev/null > +++ b/lib/uklock/include/uk/semaphore.h > @@ -0,0 +1,146 @@ > +/* 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_LIBUKLOCK_SEMAPHORE > +#include <uk/print.h> > +#include <uk/assert.h> > +#include <uk/plat/lcpu.h> > +#include <uk/thread.h> > +#include <uk/wait.h> > +#include <uk/wait_types.h> > +#include <uk/plat/time.h> > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +/* > + * 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_EXTRA, "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_EXTRA, "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_EXTRA, "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_EXTRA, "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_EXTRA, "Increased semaphore %p to %ld\n", > + s, s->count); > + uk_waitq_wake_up(&s->wait); > + ukplat_lcpu_restore_irqf(irqf); > +} > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* CONFIG_LIBUKLOCK_SEMAPHORE */ > + > +#endif /* __UK_SEMAPHORE_H__ */ > diff --git a/lib/uklock/mutex.c b/lib/uklock/mutex.c > new file mode 100644 > index 0000000..183a01d > --- /dev/null > +++ b/lib/uklock/mutex.c > @@ -0,0 +1,7 @@ > +#include <uk/mutex.h> > + > +void uk_mutex_init(struct uk_mutex *m) > +{ > + m->locked = 0; > + uk_waitq_init(&m->wait); > +} > diff --git a/lib/uklock/semaphore.c b/lib/uklock/semaphore.c > new file mode 100644 > index 0000000..0801bf6 > --- /dev/null > +++ b/lib/uklock/semaphore.c > @@ -0,0 +1,10 @@ > +#include <uk/semaphore.h> > + > +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); > +} > -- > 2.7.4 > -- Yuri Volchkov Software Specialist NEC Europe Ltd Kurfürsten-Anlage 36 D-69115 Heidelberg _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |