Minor queue optimisations.
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2758
1d2547de-c912-0410-9cb9-
b8ca96c0e9e2
* Checks to see if a queue is a member of a queue set, and if so, notifies\r
* the queue set that the queue contains data.\r
*/\r
* Checks to see if a queue is a member of a queue set, and if so, notifies\r
* the queue set that the queue contains data.\r
*/\r
- static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION;\r
+ static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue ) PRIVILEGED_FUNCTION;\r
\r
configASSERT( uxQueueLength > ( UBaseType_t ) 0 );\r
\r
\r
configASSERT( uxQueueLength > ( UBaseType_t ) 0 );\r
\r
- if( uxItemSize == ( UBaseType_t ) 0 )\r
- {\r
- /* There is not going to be a queue storage area. */\r
- xQueueSizeInBytes = ( size_t ) 0;\r
- }\r
- else\r
- {\r
- /* Allocate enough space to hold the maximum number of items that\r
- can be in the queue at any time. */\r
- xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */\r
- }\r
+ /* Allocate enough space to hold the maximum number of items that\r
+ can be in the queue at any time. It is valid for uxItemSize to be\r
+ zero in the case the queue is used as a semaphore. */\r
+ xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */\r
\r
/* Allocate the queue and storage area. Justification for MISRA\r
deviation as follows: pvPortMalloc() always ensures returned memory\r
\r
/* Allocate the queue and storage area. Justification for MISRA\r
deviation as follows: pvPortMalloc() always ensures returned memory\r
\r
#if ( configUSE_QUEUE_SETS == 1 )\r
{\r
\r
#if ( configUSE_QUEUE_SETS == 1 )\r
{\r
- UBaseType_t uxPreviousMessagesWaiting = pxQueue->uxMessagesWaiting;\r
+ const UBaseType_t uxPreviousMessagesWaiting = pxQueue->uxMessagesWaiting;\r
\r
xYieldRequired = prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
\r
\r
xYieldRequired = prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
\r
in the queue has not changed. */\r
mtCOVERAGE_TEST_MARKER();\r
}\r
in the queue has not changed. */\r
mtCOVERAGE_TEST_MARKER();\r
}\r
- else if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) != pdFALSE )\r
+ else if( prvNotifyQueueSetContainer( pxQueue ) != pdFALSE )\r
{\r
/* The queue is a member of a queue set, and posting\r
to the queue set caused a higher priority task to\r
{\r
/* The queue is a member of a queue set, and posting\r
to the queue set caused a higher priority task to\r
\r
traceQUEUE_SEND_FROM_ISR( pxQueue );\r
\r
\r
traceQUEUE_SEND_FROM_ISR( pxQueue );\r
\r
- /* Semaphores use xQueueGiveFromISR(), so pxQueue will not be a\r
- semaphore or mutex. That means prvCopyDataToQueue() cannot result\r
- in a task disinheriting a priority and prvCopyDataToQueue() can be\r
- called here even though the disinherit function does not check if\r
- the scheduler is suspended before accessing the ready lists. */\r
- ( void ) prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
-\r
/* The event list is not altered if the queue is locked. This will\r
be done when the queue is unlocked later. */\r
if( cTxLock == queueUNLOCKED )\r
{\r
#if ( configUSE_QUEUE_SETS == 1 )\r
{\r
/* The event list is not altered if the queue is locked. This will\r
be done when the queue is unlocked later. */\r
if( cTxLock == queueUNLOCKED )\r
{\r
#if ( configUSE_QUEUE_SETS == 1 )\r
{\r
+ const UBaseType_t uxPreviousMessagesWaiting = pxQueue->uxMessagesWaiting;\r
+\r
+ /* Semaphores use xQueueGiveFromISR(), so pxQueue will not be a\r
+ semaphore or mutex. That means prvCopyDataToQueue() cannot result\r
+ in a task disinheriting a priority and prvCopyDataToQueue() can be\r
+ called here even though the disinherit function does not check if\r
+ the scheduler is suspended before accessing the ready lists. */\r
+ ( void ) prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
+\r
if( pxQueue->pxQueueSetContainer != NULL )\r
{\r
if( pxQueue->pxQueueSetContainer != NULL )\r
{\r
- if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) != pdFALSE )\r
+ if( ( xCopyPosition == queueOVERWRITE ) && ( uxPreviousMessagesWaiting != ( UBaseType_t ) 0 ) )\r
+ {\r
+ /* Do not notify the queue set as an existing item\r
+ was overwritten in the queue so the number of items\r
+ in the queue has not changed. */\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
+ else if( prvNotifyQueueSetContainer( pxQueue ) != pdFALSE )\r
{\r
/* The queue is a member of a queue set, and posting\r
to the queue set caused a higher priority task to\r
{\r
/* The queue is a member of a queue set, and posting\r
to the queue set caused a higher priority task to\r
}\r
#else /* configUSE_QUEUE_SETS */\r
{\r
}\r
#else /* configUSE_QUEUE_SETS */\r
{\r
+ /* Semaphores use xQueueGiveFromISR(), so pxQueue will not be a\r
+ semaphore or mutex. That means prvCopyDataToQueue() cannot result\r
+ in a task disinheriting a priority and prvCopyDataToQueue() can be\r
+ called here even though the disinherit function does not check if\r
+ the scheduler is suspended before accessing the ready lists. */\r
+ ( void ) prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
+\r
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
{\r
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
{\r
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
{\r
if( pxQueue->pxQueueSetContainer != NULL )\r
{\r
{\r
if( pxQueue->pxQueueSetContainer != NULL )\r
{\r
- if( prvNotifyQueueSetContainer( pxQueue, queueSEND_TO_BACK ) != pdFALSE )\r
+ if( prvNotifyQueueSetContainer( pxQueue ) != pdFALSE )\r
{\r
/* The semaphore is a member of a queue set, and\r
posting to the queue set caused a higher priority\r
{\r
/* The semaphore is a member of a queue set, and\r
posting to the queue set caused a higher priority\r
{\r
if( pxQueue->pxQueueSetContainer != NULL )\r
{\r
{\r
if( pxQueue->pxQueueSetContainer != NULL )\r
{\r
- if( prvNotifyQueueSetContainer( pxQueue, queueSEND_TO_BACK ) != pdFALSE )\r
+ if( prvNotifyQueueSetContainer( pxQueue ) != pdFALSE )\r
{\r
/* The queue is a member of a queue set, and posting to\r
the queue set caused a higher priority task to unblock.\r
{\r
/* The queue is a member of a queue set, and posting to\r
the queue set caused a higher priority task to unblock.\r
\r
#if ( configUSE_QUEUE_SETS == 1 )\r
\r
\r
#if ( configUSE_QUEUE_SETS == 1 )\r
\r
- static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue, const BaseType_t xCopyPosition )\r
+ static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue )\r
{\r
Queue_t *pxQueueSetContainer = pxQueue->pxQueueSetContainer;\r
BaseType_t xReturn = pdFALSE;\r
{\r
Queue_t *pxQueueSetContainer = pxQueue->pxQueueSetContainer;\r
BaseType_t xReturn = pdFALSE;\r
traceQUEUE_SEND( pxQueueSetContainer );\r
\r
/* The data copied is the handle of the queue that contains data. */\r
traceQUEUE_SEND( pxQueueSetContainer );\r
\r
/* The data copied is the handle of the queue that contains data. */\r
- xReturn = prvCopyDataToQueue( pxQueueSetContainer, &pxQueue, xCopyPosition );\r
+ xReturn = prvCopyDataToQueue( pxQueueSetContainer, &pxQueue, queueSEND_TO_BACK );\r
\r
if( cTxLock == queueUNLOCKED )\r
{\r
\r
if( cTxLock == queueUNLOCKED )\r
{\r