nano_lifo: allow multiple fibers to pend

The nanokernel LIFOs could only have one fiber pending on one of
them concurrently. If a second fiber wanted to take a contested
LIFO, 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 LIFOs now make use of the fiber pend queue, and thus
allow multiple fibers to pend concurrently.

sysgen is updated since the microkernel initializes statically two
LIFOs, one for the command packets and one for the timer packets, and
the LIFO data structure has changed.

The nano_timers use the LIFOs and look at their internals, so they are
updated as well.

Change-Id: I250a610fcdee9d32172c88d38e6c3cfd5b437d15
Signed-off-by: Benjamin Walsh <benjamin.walsh@windriver.com>
This commit is contained in:
Benjamin Walsh 2015-05-04 22:05:39 -04:00 committed by Anas Nashif
parent 7a7ba579c5
commit b4484a7816
4 changed files with 12 additions and 15 deletions

View file

@ -50,8 +50,8 @@ struct nano_sem {
};
struct nano_lifo {
struct _nano_queue wait_q;
void *list;
tCCS *proc;
};
struct nano_fifo {

View file

@ -49,6 +49,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,7 +73,7 @@ void nano_lifo_init(
)
{
lifo->list = (void *)0;
lifo->proc = (tCCS *)0;
_nano_wait_q_init(&lifo->wait_q);
}
#ifdef CONFIG_MICROKERNEL
@ -115,12 +116,9 @@ void _lifo_put(
unsigned int imask;
imask = irq_lock_inline();
ccs = lifo->proc;
ccs = _nano_wait_q_remove(&lifo->wait_q);
if (ccs != (tCCS *)NULL) {
lifo->proc = (tCCS *)0;
fiberRtnValueSet(ccs, (unsigned int)data);
_insert_ccs((tCCS **)&_NanoKernel.fiber, ccs);
} else {
*(void **)data = lifo->list;
lifo->list = data;
@ -151,12 +149,9 @@ void nano_task_lifo_put(
unsigned int imask;
imask = irq_lock_inline();
ccs = lifo->proc;
ccs = _nano_wait_q_remove(&lifo->wait_q);
if (ccs != (tCCS *)NULL) {
lifo->proc = (tCCS *)0;
fiberRtnValueSet(ccs, (unsigned int)data);
_insert_ccs((tCCS **)&_NanoKernel.fiber, ccs);
/* swap into the newly ready fiber */
@ -245,7 +240,7 @@ void *nano_fiber_lifo_get_wait(
imask = irq_lock_inline();
if (lifo->list == NULL) {
lifo->proc = _NanoKernel.current;
_nano_wait_q_put(&lifo->wait_q);
data = (void *)_Swap(imask);
} else {
data = lifo->list;

View file

@ -195,7 +195,7 @@ void nano_fiber_timer_stop(struct nano_timer *timer /* timer to stop */
_timer_stop(timer);
/* if there was a waiter, kick it */
if (timer->lifo.proc) {
if (timer->lifo.wait_q.head) {
nano_fiber_lifo_put(&timer->lifo, (void *)0);
}
}
@ -217,7 +217,7 @@ void nano_task_timer_stop(struct nano_timer *timer /* timer to stop */
_timer_stop(timer);
/* if there was a waiter, kick it */
if (timer->lifo.proc) {
if (timer->lifo.wait_q.head) {
nano_task_lifo_put(&timer->lifo, (void *)0);
}
}

View file

@ -330,7 +330,8 @@ def kernel_main_c_kargs():
kernel_main_c_out("\n" +
"struct nano_lifo _k_server_command_packet_free = " +
"{(void *) &K_ArgsBlocks[%d], NULL};\n" % (num_kargs - 1))
"{{NULL, &_k_server_command_packet_free.wait_q.head}, " +
"(void *) &K_ArgsBlocks[%d]};\n" % (num_kargs - 1))
def kernel_main_c_timers():
@ -358,7 +359,8 @@ def kernel_main_c_timers():
kernel_main_c_out("\n" +
"struct nano_lifo _k_timer_free = " +
"{(void *) &K_TimerBlocks[%d], NULL};\n" % (num_timers - 1))
"{{NULL, &_k_timer_free.wait_q.head}, " +
"(void *) &K_TimerBlocks[%d]};\n" % (num_timers - 1))
def kernel_main_c_tasks():