[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [UNIKRAFT PATCH] Made ukmpi and uklock interrupt-context-safe
From: Cristian Vijelie <cristianvijelie@xxxxxxxxx> For semaphore and mutex, the only change needed for now was to create some aliases to some inlined functions, that can be called in an interupt context, in 'uk/isr/mutex.h' and 'uk/isr/semaphore.h'. For mbox, I moved the functions that can be called in an interupt context to a separate sorce file, 'mbox_isr.c', and I also moved some static inlined functions needed by both mbox and mbox_isr in the mbox.h header, along with th definition of struct uk_mbox. Signed-off-by: Cristian Vijelie <cristianvijelie@xxxxxxxxx> --- include/uk/isr/mbox.h | 13 +++++++++ include/uk/isr/mutex.h | 8 ++++++ include/uk/isr/semaphore.h | 8 ++++++ lib/ukmpi/Makefile.uk | 1 + lib/ukmpi/include/uk/mbox.h | 54 ++++++++++++++++++++++++++++++++++++- lib/ukmpi/mbox.c | 54 ------------------------------------- lib/ukmpi/mbox_isr.c | 39 +++++++++++++++++++++++++++ 7 files changed, 122 insertions(+), 55 deletions(-) create mode 100644 include/uk/isr/mbox.h create mode 100644 include/uk/isr/mutex.h create mode 100644 include/uk/isr/semaphore.h create mode 100644 lib/ukmpi/mbox_isr.c diff --git a/include/uk/isr/mbox.h b/include/uk/isr/mbox.h new file mode 100644 index 0000000..ef70939 --- /dev/null +++ b/include/uk/isr/mbox.h @@ -0,0 +1,13 @@ +#ifndef __MBOX_ISR_H__ +#define __MBOX_ISR_H__ + +#include <uk/mbox.h> + +#if CONFIG_LIBUKMPI_MBOX + +int uk_mbox_post_try_isr(struct uk_mbox *m, void *msg); +int uk_mbox_recv_try_isr(struct uk_mbox *m, void **msg); + +#endif /* CONFIG_LIBUKMPI_MBOX */ + +#endif /* __MBOX_ISR_H__ */ \ No newline at end of file diff --git a/include/uk/isr/mutex.h b/include/uk/isr/mutex.h new file mode 100644 index 0000000..06d51f8 --- /dev/null +++ b/include/uk/isr/mutex.h @@ -0,0 +1,8 @@ +#ifndef __UK_ISR_MUTEX_H__ +#define __UK_ISR_MUTEX_H__ + +#include <uk/mutex.h> + +#define uk_mutex_trylock_isr(x) uk_mutex_trylock(x) + +#endif /* __UK_ISR_MUTEX_H__ */ \ No newline at end of file diff --git a/include/uk/isr/semaphore.h b/include/uk/isr/semaphore.h new file mode 100644 index 0000000..b187f1f --- /dev/null +++ b/include/uk/isr/semaphore.h @@ -0,0 +1,8 @@ +#ifndef __UK_ISR_SEMAPHORE_H__ +#define __UK_ISR_SEMAPHORE_H__ + +#include <uk/semaphore.h> + +#define uk_semaphore_down_try_isr(x) uk_semaphore_down_try(x) + +#endif /* __UK_ISR_SEMAPHORE_H__ */ \ No newline at end of file diff --git a/lib/ukmpi/Makefile.uk b/lib/ukmpi/Makefile.uk index fc8a360..49df296 100644 --- a/lib/ukmpi/Makefile.uk +++ b/lib/ukmpi/Makefile.uk @@ -4,3 +4,4 @@ CINCLUDES-$(CONFIG_LIBUKMPI) += -I$(LIBUKMPI_BASE)/include CXXINCLUDES-$(CONFIG_LIBUKMPI) += -I$(LIBUKMPI_BASE)/include LIBUKMPI_SRCS-$(CONFIG_LIBUKMPI_MBOX) += $(LIBUKMPI_BASE)/mbox.c +LIBUKMPI_SRCS-$(CONFIG_LIBUKMPI_MBOX) += $(LIBUKMPI_BASE)/mbox_isr.c|isr diff --git a/lib/ukmpi/include/uk/mbox.h b/lib/ukmpi/include/uk/mbox.h index 19b1ecc..37146d6 100644 --- a/lib/ukmpi/include/uk/mbox.h +++ b/lib/ukmpi/include/uk/mbox.h @@ -47,7 +47,15 @@ extern "C" { #endif /* __cplusplus */ -struct uk_mbox; +struct uk_mbox { + size_t len; + struct uk_semaphore readsem; + long readpos; + struct uk_semaphore writesem; + long writepos; + + void *msgs[]; +}; struct uk_mbox *uk_mbox_create(struct uk_alloc *a, size_t size); void uk_mbox_free(struct uk_alloc *a, struct uk_mbox *m); @@ -60,6 +68,50 @@ void uk_mbox_recv(struct uk_mbox *m, void **msg); int uk_mbox_recv_try(struct uk_mbox *m, void **msg); __nsec uk_mbox_recv_to(struct uk_mbox *m, void **msg, __nsec timeout); +/* Posts the "msg" to the mailbox, internal version that actually does the + * post. + */ +static inline void _do_mbox_post(struct uk_mbox *m, void *msg) +{ + /* The caller got a semaphore token, so we are now allowed to increment + * writer, but we still need to prevent concurrency between writers + * (interrupt handler vs main) + */ + unsigned long irqf; + + UK_ASSERT(m); + + irqf = ukplat_lcpu_save_irqf(); + m->msgs[m->writepos] = msg; + m->writepos = (m->writepos + 1) % m->len; + UK_ASSERT(m->readpos != m->writepos); + ukplat_lcpu_restore_irqf(irqf); + uk_pr_debug("Posted message %p to mailbox %p\n", msg, m); + + uk_semaphore_up(&m->readsem); +} + +/* + * Fetch a message from a mailbox. Internal version that actually does the + * fetch. + */ +static inline void *_do_mbox_recv(struct uk_mbox *m) +{ + unsigned long irqf; + void *ret; + + uk_pr_debug("Receive message from mailbox %p\n", m); + irqf = ukplat_lcpu_save_irqf(); + UK_ASSERT(m->readpos != m->writepos); + ret = m->msgs[m->readpos]; + m->readpos = (m->readpos + 1) % m->len; + ukplat_lcpu_restore_irqf(irqf); + + uk_semaphore_up(&m->writesem); + + return ret; +} + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/lib/ukmpi/mbox.c b/lib/ukmpi/mbox.c index 149a667..b223ced 100644 --- a/lib/ukmpi/mbox.c +++ b/lib/ukmpi/mbox.c @@ -2,16 +2,6 @@ #include <uk/assert.h> #include <uk/arch/limits.h> -struct uk_mbox { - size_t len; - struct uk_semaphore readsem; - long readpos; - struct uk_semaphore writesem; - long writepos; - - void *msgs[]; -}; - struct uk_mbox *uk_mbox_create(struct uk_alloc *a, size_t size) { struct uk_mbox *m; @@ -49,29 +39,6 @@ void uk_mbox_free(struct uk_alloc *a, struct uk_mbox *m) uk_free(a, m); } -/* Posts the "msg" to the mailbox, internal version that actually does the - * post. - */ -static inline void _do_mbox_post(struct uk_mbox *m, void *msg) -{ - /* The caller got a semaphore token, so we are now allowed to increment - * writer, but we still need to prevent concurrency between writers - * (interrupt handler vs main) - */ - unsigned long irqf; - - UK_ASSERT(m); - - irqf = ukplat_lcpu_save_irqf(); - m->msgs[m->writepos] = msg; - m->writepos = (m->writepos + 1) % m->len; - UK_ASSERT(m->readpos != m->writepos); - ukplat_lcpu_restore_irqf(irqf); - uk_pr_debug("Posted message %p to mailbox %p\n", msg, m); - - uk_semaphore_up(&m->readsem); -} - void uk_mbox_post(struct uk_mbox *m, void *msg) { /* The caller got a semaphore token, so we are now allowed to increment @@ -106,27 +73,6 @@ __nsec uk_mbox_post_to(struct uk_mbox *m, void *msg, __nsec timeout) return ret; } -/* - * Fetch a message from a mailbox. Internal version that actually does the - * fetch. - */ -static inline void *_do_mbox_recv(struct uk_mbox *m) -{ - unsigned long irqf; - void *ret; - - uk_pr_debug("Receive message from mailbox %p\n", m); - irqf = ukplat_lcpu_save_irqf(); - UK_ASSERT(m->readpos != m->writepos); - ret = m->msgs[m->readpos]; - m->readpos = (m->readpos + 1) % m->len; - ukplat_lcpu_restore_irqf(irqf); - - uk_semaphore_up(&m->writesem); - - return ret; -} - /* Blocks the thread until a message arrives in the mailbox. * The `*msg` argument will point to the received message. * If the `msg` parameter was set to NULL, the received message is dropped. diff --git a/lib/ukmpi/mbox_isr.c b/lib/ukmpi/mbox_isr.c new file mode 100644 index 0000000..43cd516 --- /dev/null +++ b/lib/ukmpi/mbox_isr.c @@ -0,0 +1,39 @@ +#include <uk/isr/mbox.h> +#include <uk/assert.h> + +int uk_mbox_post_try_isr(struct uk_mbox *m, void *msg) +{ + UK_ASSERT(m); + + if (!uk_semaphore_down_try(&m->writesem)) + return -ENOBUFS; + _do_mbox_post(m, msg); + return 0; +} + +/* This is similar to uk_mbox_fetch, however if a message is not + * present in the mailbox, it immediately returns with the code + * SYS_MBOX_EMPTY. On success 0 is returned. + * + * To allow for efficient implementations, this can be defined as a + * function-like macro in sys_arch.h instead of a normal function. For + * example, a naive implementation could be: + * #define uk_mbox_tryfetch(mbox,msg) \ + * uk_mbox_fetch(mbox,msg,1) + * although this would introduce unnecessary delays. + */ + +int uk_mbox_recv_try_isr(struct uk_mbox *m, void **msg) +{ + void *rmsg; + + UK_ASSERT(m); + + if (!uk_semaphore_down_try(&m->readsem)) + return -ENOMSG; + + rmsg = _do_mbox_recv(m); + if (msg) + *msg = rmsg; + return 0; +} \ No newline at end of file -- 2.25.1 |
Lists.xenproject.org is hosted with RackSpace, monitoring our |