blocking on receive with suspend all active

anonymous wrote on Thursday, May 01, 2008:

Unintentionally my system blocked on a receive after calling vTaskSuspendAll(). It is unclear to me what the intended FreeRTOS behaviour is, but the behaviour I observed seems to be a FreeRTOS bug.

In xQueueGenericReceive(), the following code is executed after the calling task is enqueued on the xTasksWaitingToReceive list.

if( !xTaskResumeAll() )

However, taskYield() does not re-schedule because scheduling is suspended. The calling task continues, ultimately hitting the end of the do-while with xReturn==queueERRONEOUS_UNBLOCK. Another iteration is performed, once again performing

vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );

But this call corrupts the list, presumably because the item is already on the list. In my case of only the one item on the list, it is corrupted such that xListEnd locates the list item, but the list item locates itself rather than xListEnd. The next search of the list becomes an infinite loop on

for( pxIterator = ( xListItem * ) &( pxList->xListEnd )
____; pxIterator->pxNext->xItemValue <= xValueOfInsertion
____; pxIterator = pxIterator->pxNext )

in vListInsert() on the next do-while iteration.


rtel wrote on Thursday, May 01, 2008:

What you are pointing out is a flaw in the documentation, rather than the code.  It is not intended or that logical that these functions get called while the scheduler is suspended, but (having just checked) the documentation does not state this.  I will update this right after posting this.

The SafeRTOS code has explicit checks for this condition, and returns an errSCHEDULER_WAS_SUSPENDED error code should it occur.

Thanks for taking the time to write your post, as a direct result the docs will be improved.


rtel wrote on Thursday, May 01, 2008:

I was going to update the docs for all the API functions to which it is relevant, but having just had a quick scan of where the errSCHEDULER_WAS_SUSPENDED error is used it seems, due to their number, more appropriate to have updated the documentation for the vTaskSuspendAll() function instead.

I have now added " API functions that have the potential to cause a context switch (for example, vTaskDelayUntil(), xQueueSend(), etc.) must not be called while the scheduler is suspended." to both the checked in header file and the .html page on the WEB site.


anonymous wrote on Thursday, May 01, 2008:

Ah, I see.

Yesterday when I discussed this with a colleague, he suggested that the suspend count should be task specific (much like the critical section nesting count). Then when this situation happened the suspend should be suspended (so to speak) - i.e. scheduling resumed… until the task unblocks.

Something to think of for the future, although I can see both pros and cons to this approach.