Queue wait forever?

westmorelandeng wrote on Saturday, October 21, 2006:

Neil,

I have taken a lot of VxWorks training and have worked with that too - but I find it a little heavy handed…<don’t want to go there…>

I may do some uC/OS-II ports soon - depends on a few things…

I cut my teeth so to speak on Nucleus - which I consider full featured - especially at the time (1993).  Started as a Ph.D. thesis if memory serves me at CalTech…

I agree with your comments re: FreeRTOS.  Hail to Richard! for sure.

I’m in San Jose - so, please, next time you’re down here indeed drop me a line.  We used to have a nice place downtown called the Pig 'N Whistle - but that’s gone the way of the dinosaurs so to speak.  We don’t have the uBreweries that you guys have up in Portland - but we do have some…

I’d like to meet with you as well next time you’re here.

Best Regards,
John W.

rtel wrote on Saturday, October 21, 2006:

I think there may be an easy option if you want a task to block without a timeout on a queue.

If a task appears in a delayed task list it is blocked with a timeout.  When the time out occurs the task will be woken from within the tick ISR.

If a task appears on the suspended task list it remains on the suspended task list until such a time that another task or an ISR un-suspends it.  It can therefore remain on the suspended task list indefinitely.

When a task blocks on a queue vTaskPlaceOnEventList() is called.  This places the calling task onto a delayed task list - to be woken when the block time expires.  If instead the task were to be placed on a suspended task list it would remain blocked/suspended until such a time that the queue event it was waiting for occurred.

Within vTaskPlaceOnEventList() the two lines:

if( xTimeToWake < xTickCount )
{
____/* Wake time has overflowed.  Place this item in the overflow list. */
____vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
}
else
{
____/* The wake time has not overflowed, so we can use the current block list. */
____vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
}

would become:

if( xTimeToWake == BLOCK_FOREVER )
{
____vListInsertEnd( ( xList * ) xSuspendedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
}
else if( xTimeToWake < xTickCount )
{
____/* Wake time has overflowed.  Place this item in the overflow list. */
____vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
}
else
{
____/* The wake time has not overflowed, so we can use the current block list. */
____vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
}

This would result in the event list item being on the queue in priority order, and the generic (state) list item being on the suspended list.

I have not tested this or done a full analysis, but it seems straight forward.  The problem would be what value to use for BLOCK_FOREVER, as the block time is an unsigned value all possible values are valid block times.  You could take portMAX_DELAY to mean that you want to block for ever, or you could introduce a new parameter to the function to indicate that you wanted to block forever - in which case the block time would be ignored.

Regards.

jwestmoreland wrote on Saturday, October 21, 2006:

Richard,

Thanks for the test code.

I can code it up soon (or Neil too) - to see how
it works - but developing a test case that really proves it’s OK will take some practical test time.

I’m using the example that I pointed out above - and it’s OK for soft real-time - I can code up what you’ve suggested but I’ll get the same result (I assume) since in my case I know that I almost never hit the timeout case - and if and when I do - it’s not a big deal.  I suppose I can play with the timeout values (making them relatively small) so test times aren’t into months…

Thanks again!
John

rtel wrote on Sunday, October 22, 2006:

I have updated tasks.c in Subversion to include this.  I quite like this change - it offers a run time efficiency improvement when blocking with portMAX_DELAY with a tiny code size increase.

Regards.

neilbradley wrote on Sunday, October 22, 2006:

Excellent! Thank you! Now I’ll just have to install Subversion. :wink:

nobody wrote on Sunday, October 22, 2006:

Try this: http://tortoisesvn.tigris.org/

nobody wrote on Friday, December 08, 2006:

Will the API documentation on the FreeRTOS web site be updated with this information?

By the way, I think there is plenty of other useful information in this forum that also should be in the docs.

rtel wrote on Friday, December 08, 2006:

Its on the todo list :wink:

Regards.

imajeff wrote on Saturday, December 16, 2006:

I wish I found this thread sooner, but I am wondering if there is currently any use for specifying xTicksToWait = 0:

xQueueReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 0 )

I thought that it would be reasonable if 0 meant no timeout. Or does anyone already use that to really mean “don’t wait”, or what exactly would it do?

But still, I have no complaint myself to use portMAX_DELAY, except that some others might have used that value and expected it to check back on occasion (perhaps rare cases). That means those would have to be changed to portMAX_DELAY-1 or something.

nobody wrote on Saturday, December 16, 2006:

Passing zero as the pararameter means don’t wait.  Return immediately even when no data is available.

In the latest version using portMAX_DELAY causes it to block to wait indefinitely if you have INCLUDE_vTaskSuspend defined as 1.  Otherwise it will cause it to block for portMAX_DELAY ticks - about 40 days on a 32 bit architecture with a tick frequency of 1KHz.

imajeff wrote on Monday, December 18, 2006:

Oh yes, for some reason I had forgot. So waiting 0 ensures it will not block. Fairly important in many cases :slight_smile: