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:
parent
194ad8da3b
commit
7a7ba579c5
2 changed files with 7 additions and 13 deletions
|
@ -45,7 +45,7 @@ struct _nano_queue {
|
|||
};
|
||||
|
||||
struct nano_sem {
|
||||
tCCS *proc;
|
||||
struct _nano_queue wait_q;
|
||||
int nsig;
|
||||
};
|
||||
|
||||
|
|
|
@ -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--;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue