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:
parent
7a7ba579c5
commit
b4484a7816
|
@ -50,8 +50,8 @@ struct nano_sem {
|
|||
};
|
||||
|
||||
struct nano_lifo {
|
||||
struct _nano_queue wait_q;
|
||||
void *list;
|
||||
tCCS *proc;
|
||||
};
|
||||
|
||||
struct nano_fifo {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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():
|
||||
|
|
Loading…
Reference in a new issue