[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Minios-devel] [UNIKRAFT PATCH 4/5] lib/uklock: Introduce libuklock
Just adding a couple of minor notes Sharan Santhanam <sharan.santhanam@xxxxxxxxx> writes: > 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; No need to change anything about it. But potentially memory barrier is needed here, if we want SMP. Just for the mental note. Or use atomic insteand > + 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); I would say this should be really the lowest debug level - DLVL_EXTRA > + 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 -- 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 |