diff --git a/include/nanokernel.h b/include/nanokernel.h index 4f6fc206cdf..740ef2f6989 100644 --- a/include/nanokernel.h +++ b/include/nanokernel.h @@ -124,6 +124,9 @@ extern void *nano_task_lifo_get_wait(struct nano_lifo *chan); /* semaphore APIs */ extern void nano_sem_init(struct nano_sem *chan); +/* scheduling context independent methods (when context is not known) */ +extern void nano_sem_give(struct nano_sem *chan); +extern void nano_sem_take_wait(struct nano_sem *chan); /* methods for ISRs */ extern void nano_isr_sem_give(struct nano_sem *chan); extern int nano_isr_sem_take(struct nano_sem *chan); diff --git a/kernel/nanokernel/core/nano_sema.c b/kernel/nanokernel/core/nano_sema.c index 82cbef84fa1..c7b3254144f 100644 --- a/kernel/nanokernel/core/nano_sema.c +++ b/kernel/nanokernel/core/nano_sema.c @@ -156,6 +156,23 @@ void nano_task_sem_give( irq_unlock_inline(imask); } +/******************************************************************************* +* +* nano_sem_give - give a nanokernel semaphore +* +* This is a convenience wrapper for the context-specific APIs. This is +* helpful whenever the exact scheduling context is not known, but should +* be avoided when the context is known up-front (to avoid unnecessary +* overhead). +*/ +void nano_sem_give(struct nano_sem *chan) +{ + static void (*func[3])(struct nano_sem *chan) = { + nano_isr_sem_give, nano_fiber_sem_give, nano_task_sem_give + }; + func[context_type_get()](chan); +} + FUNC_ALIAS(_sem_take, nano_isr_sem_take, int); FUNC_ALIAS(_sem_take, nano_fiber_sem_take, int); FUNC_ALIAS(_sem_take, nano_task_sem_take, int); @@ -279,3 +296,22 @@ void nano_task_sem_take_wait( chan->nsig--; irq_unlock_inline(imask); } + +/******************************************************************************* +* +* nano_sem_take_wait - take a nanokernel semaphore, poll/pend if not available +* +* This is a convenience wrapper for the context-specific APIs. This is +* helpful whenever the exact scheduling context is not known, but should +* be avoided when the context is known up-front (to avoid unnecessary +* overhead). +* +* It's only valid to call this API from a fiber or a task. +*/ +void nano_sem_take_wait(struct nano_sem *chan) +{ + static void (*func[3])(struct nano_sem *chan) = { + NULL, nano_fiber_sem_take_wait, nano_task_sem_take_wait + }; + func[context_type_get()](chan); +}