nano_sem: allow multiple fibers to pend

The nanokernel semaphores could only have one fiber pending on one of
them concurrently. If a second fiber wanted to take a contested
semaphore, if would kick the pending fiber out of the wait 'container',
but would not put it in back in the ready queue with an error. Instead,
it would, for all intents and purposes, remove it from the scheduling
mechanism of the nanokernel: the fiber would be 'lost' at that point.

The nanokernel semaphores now make use of the fiber pend queue, and thus
allow multiple fibers to pend concurrently.

Change-Id: If8a8cee55d47fa1454ee84c56950fd4da20cd436
Signed-off-by: Benjamin Walsh <benjamin.walsh@windriver.com>
This commit is contained in:
Benjamin Walsh 2015-05-04 21:53:54 -04:00 committed by Anas Nashif
commit 7a7ba579c5
2 changed files with 7 additions and 13 deletions

View file

@ -45,7 +45,7 @@ struct _nano_queue {
};
struct nano_sem {
tCCS *proc;
struct _nano_queue wait_q;
int nsig;
};

View file

@ -55,6 +55,7 @@ APIs to the same function, since they have identical implementations.
#include <nanok.h>
#include <toolchain.h>
#include <sections.h>
#include <wait_q.h>
/*******************************************************************************
*
@ -78,7 +79,7 @@ void nano_sem_init(
)
{
sem->nsig = 0;
sem->proc = (tCCS *)0;
_nano_wait_q_init(&sem->wait_q);
}
FUNC_ALIAS(_sem_give, nano_isr_sem_give, void);
@ -110,11 +111,8 @@ void _sem_give(
unsigned int imask;
imask = irq_lock_inline();
ccs = sem->proc;
if (ccs != (tCCS *)NULL) {
sem->proc = 0;
_insert_ccs((tCCS **)&_NanoKernel.fiber, ccs);
} else {
ccs = _nano_wait_q_remove(&sem->wait_q);
if (!ccs) {
sem->nsig++;
}
@ -140,13 +138,9 @@ void nano_task_sem_give(
unsigned int imask;
imask = irq_lock_inline();
ccs = sem->proc;
ccs = _nano_wait_q_remove(&sem->wait_q);
if (ccs != (tCCS *)NULL) {
sem->proc = 0;
_insert_ccs((tCCS **)&_NanoKernel.fiber, ccs);
/* swap into the newly ready fiber */
_Swap(imask);
return;
} else {
@ -232,7 +226,7 @@ void nano_fiber_sem_take_wait(
imask = irq_lock_inline();
if (sem->nsig == 0) {
sem->proc = _NanoKernel.current;
_nano_wait_q_put(&sem->wait_q);
_Swap(imask);
} else {
sem->nsig--;