nano_fifo: use struct _nano_queue and _nano_wait_q routines

Adapt nano_fifo to use the struct _nano_queue and the _nano_wait_q
interface built on it.

The nano_fifo is the first to be adapted to use these since it currently
is the only nanokernel object that can handle multiple waiters, and the
_nano_wait_q abstraction was taken directly from it. This allows an easy
transition and can reuse the same tests to verify the abstraction is
working correctly.

Change-Id: Ie96e6cf1cb21c99ab2fb9832f9b454a9e1ebd300
Signed-off-by: Benjamin Walsh <benjamin.walsh@windriver.com>
This commit is contained in:
Benjamin Walsh 2015-05-04 18:27:59 -04:00 committed by Anas Nashif
commit 194ad8da3b
2 changed files with 21 additions and 29 deletions

View file

@ -55,8 +55,13 @@ struct nano_lifo {
};
struct nano_fifo {
void *head;
void *tail;
union {
struct _nano_queue wait_q;
struct {
void *head;
void *tail;
};
};
int stat;
};

View file

@ -50,6 +50,7 @@ APIs to the same function, since they have identical implementations.
#include <nanok.h>
#include <toolchain.h>
#include <sections.h>
#include <wait_q.h>
/*******************************************************************************
*
@ -72,8 +73,13 @@ void nano_fifo_init(
struct nano_fifo *fifo /* fifo to initialize */
)
{
fifo->head = (void *)0;
fifo->tail = (void *)&(fifo->head);
/*
* The wait queue and data queue occupy the same space since there cannot
* be both queued data and pending fibers in the FIFO. Care must be taken
* that, when one of the queues becomes empty, it is reset to a state
* that reflects an empty queue to both the data and wait queues.
*/
_nano_wait_q_init(&fifo->wait_q);
/*
* If the 'stat' field is a positive value, it indicates how many data
@ -114,23 +120,14 @@ void _fifo_put(
void *data /* data to send */
)
{
tCCS *ccs;
unsigned int imask;
imask = irq_lock_inline();
fifo->stat++;
if (fifo->stat <= 0) {
ccs = fifo->head;
if (fifo->stat == 0) {
fifo->tail = (void *)&fifo->head;
} else {
fifo->head = ccs->link;
}
ccs->link = 0;
tCCS *ccs = _nano_wait_q_remove_no_check(&fifo->wait_q);
fiberRtnValueSet(ccs, (unsigned int)data);
_insert_ccs((tCCS **)&_NanoKernel.fiber, ccs);
} else {
*(void **)fifo->tail = data;
fifo->tail = data;
@ -159,23 +156,14 @@ void nano_task_fifo_put(
void *data /* data to send */
)
{
tCCS *ccs;
unsigned int imask;
imask = irq_lock_inline();
fifo->stat++;
if (fifo->stat <= 0) {
ccs = fifo->head;
if (fifo->stat == 0) {
fifo->tail = (void *)&fifo->head;
} else {
fifo->head = ccs->link;
}
ccs->link = 0;
tCCS *ccs = _nano_wait_q_remove_no_check(&fifo->wait_q);
fiberRtnValueSet(ccs, (unsigned int)data);
_insert_ccs((tCCS **)&_NanoKernel.fiber, ccs);
/* swap into the fiber just made ready */
@ -247,7 +235,7 @@ void *_fifo_get(
data = fifo->head;
if (fifo->stat == 0) {
fifo->tail = (void *)&(fifo->head);
_nano_wait_q_reset(&fifo->wait_q);
} else {
fifo->head = *(void **)data;
}
@ -287,13 +275,12 @@ void *nano_fiber_fifo_get_wait(
fifo->stat--;
if (fifo->stat < 0) {
((tCCS *)fifo->tail)->link = _NanoKernel.current;
fifo->tail = _NanoKernel.current;
_nano_wait_q_put(&fifo->wait_q);
data = (void *)_Swap(imask);
} else {
data = fifo->head;
if (fifo->stat == 0) {
fifo->tail = (void *)&fifo->head;
_nano_wait_q_reset(&fifo->wait_q);
} else {
fifo->head = *(void **)data;
}
@ -349,7 +336,7 @@ void *nano_task_fifo_get_wait(
data = fifo->head;
if (fifo->stat == 0)
fifo->tail = (void *)&(fifo->head);
_nano_wait_q_reset(&fifo->wait_q);
else
fifo->head = *(void **)data;