microbit: More efficient handling of events

Removed unnecessary queing of item on the MessageBus, whilst maintaining causal ordering.
This commit is contained in:
Joe Finney 2015-11-01 15:16:27 +00:00
parent b2e9369771
commit 39abf824dc
1 changed files with 33 additions and 39 deletions

View File

@ -97,54 +97,48 @@ void MicroBitMessageBus::queueEvent(MicroBitEvent &evt)
{ {
int processingComplete; int processingComplete;
if (queueLength >= MESSAGE_BUS_LISTENER_MAX_QUEUE_DEPTH) MicroBitEventQueueItem *prev = evt_queue_tail;
return;
MicroBitEventQueueItem *item = new MicroBitEventQueueItem(evt);
MicroBitEventQueueItem *prev;
// Queue this event. We always do this to maintain event ordering...
// It costs a a little time and memory, but is worth it.
__disable_irq();
prev = evt_queue_tail;
if (evt_queue_tail == NULL)
{
evt_queue_head = evt_queue_tail = item;
}
else
{
evt_queue_tail->next = item;
evt_queue_tail = item;
}
queueLength++;
__enable_irq();
// Now process all handler regsitered as URGENT. // Now process all handler regsitered as URGENT.
// These pre-empt the queue, and are useful for fast, high priority services. // These pre-empt the queue, and are useful for fast, high priority services.
processingComplete = this->process(evt, true); processingComplete = this->process(evt, true);
// If we've already processed all event handlers, we're all done.
// No need to queue the event.
if (processingComplete) if (processingComplete)
return;
// If we need to queue, but there is no space, then there's nothg we can do.
if (queueLength >= MESSAGE_BUS_LISTENER_MAX_QUEUE_DEPTH)
return;
// Otherwise, we need to queue this event for later processing...
// We queue this event at the tail of the queue at the point where we entered queueEvent()
// This is important as the processing above *may* have generated further events, and
// we want to maintain ordering of events.
MicroBitEventQueueItem *item = new MicroBitEventQueueItem(evt);
// The queue was empty when we entered this function, so queue our event at the start of the queue.
__disable_irq();
if (prev == NULL)
{ {
// No more processing is required... drop the event from the list to avoid the need for processing later. item->next = evt_queue_head;
if (evt_queue_head == item) evt_queue_head = item;
evt_queue_head = item->next; }
else
if (evt_queue_tail == item) {
evt_queue_tail = prev; item->next = prev->next;
prev->next = item;
if (prev)
prev->next = item->next;
queueLength--;
delete item;
} }
}
if (item->next == NULL)
evt_queue_tail = item;
queueLength++;
__enable_irq();
}
/** /**
* Extract the next event from the front of the event queue (if present). * Extract the next event from the front of the event queue (if present).