nanokernel: Add scheduling context-independent API for semaphores

When the exact scheduling context is not known it's convenient to have
a wrapper API that uses context_type_get() to call the right function
at runtime.

Change-Id: I02b2ac9039519468f5501571243426a6a57ffc4d
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2015-04-16 12:29:21 +03:00 committed by Anas Nashif
commit 9599f21dfb
2 changed files with 39 additions and 0 deletions

View file

@ -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);

View file

@ -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);
}