* Copies an item into the queue, either at the front of the queue or the\r
* back of the queue.\r
*/\r
-static void prvCopyDataToQueue( Queue_t * const pxQueue, const void *pvItemToQueue, const BaseType_t xPosition ) PRIVILEGED_FUNCTION;\r
+static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, const void *pvItemToQueue, const BaseType_t xPosition ) PRIVILEGED_FUNCTION;\r
\r
/*\r
* Copies an item out of a queue.\r
\r
traceCREATE_MUTEX( pxNewQueue );\r
\r
- /* Start with the semaphore in the expected state. */\r
+ /* Start with the semaphore in the expected state. Preload the\r
+ mutex held count as calling xQueueGenericSend() will decrement the\r
+ count back to 0. */\r
+ vTaskIncrementMutexHeldCount();\r
( void ) xQueueGenericSend( pxNewQueue, NULL, ( TickType_t ) 0U, queueSEND_TO_BACK );\r
}\r
else\r
}\r
else\r
{\r
- /* We cannot give the mutex because we are not the holder. */\r
+ /* The mutex cannot be given because the calling task is not the \r
+ holder. */\r
xReturn = pdFAIL;\r
\r
traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex );\r
{\r
xReturn = xQueueGenericReceive( pxMutex, NULL, xTicksToWait, pdFALSE );\r
\r
- /* pdPASS will only be returned if we successfully obtained the mutex,\r
- we may have blocked to reach here. */\r
+ /* pdPASS will only be returned if the mutex was successfully \r
+ obtained. The calling task may have entered the Blocked state\r
+ before reaching here. */\r
if( xReturn == pdPASS )\r
{\r
( pxMutex->u.uxRecursiveCallCount )++;\r
\r
BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition )\r
{\r
-BaseType_t xEntryTimeSet = pdFALSE;\r
+BaseType_t xEntryTimeSet = pdFALSE, xYieldRequired;\r
TimeOut_t xTimeOut;\r
Queue_t * const pxQueue = ( Queue_t * ) xQueue;\r
\r
if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) )\r
{\r
traceQUEUE_SEND( pxQueue );\r
- prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
+ xYieldRequired = prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
\r
#if ( configUSE_QUEUE_SETS == 1 )\r
{\r
mtCOVERAGE_TEST_MARKER();\r
}\r
}\r
+ else if( xYieldRequired != pdFALSE )\r
+ {\r
+ /* This path is a special case that will only get\r
+ executed if the task was holding multiple mutexes\r
+ and the mutexes were given back in an order that is\r
+ different to that in which they were taken. */\r
+ queueYIELD_IF_USING_PREEMPTION();\r
+ }\r
else\r
{\r
mtCOVERAGE_TEST_MARKER();\r
#endif /* configUSE_QUEUE_SETS */\r
\r
taskEXIT_CRITICAL();\r
-\r
- /* Return to the original privilege level before exiting the\r
- function. */\r
return pdPASS;\r
}\r
else\r
{\r
traceQUEUE_SEND_FROM_ISR( pxQueue );\r
\r
- prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
+ if( prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ) != pdFALSE )\r
+ {\r
+ /* This is a special case that can only be executed if a task\r
+ holds multiple mutexes and then gives the mutexes back in an\r
+ order that is different to that in which they were taken. */\r
+ if( pxHigherPriorityTaskWoken != NULL )\r
+ {\r
+ *pxHigherPriorityTaskWoken = pdTRUE;\r
+ }\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
+ }\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
#endif /* configUSE_TRACE_FACILITY */\r
/*-----------------------------------------------------------*/\r
\r
-static void prvCopyDataToQueue( Queue_t * const pxQueue, const void *pvItemToQueue, const BaseType_t xPosition )\r
+static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, const void *pvItemToQueue, const BaseType_t xPosition )\r
{\r
+BaseType_t xReturn = pdFALSE;\r
+\r
if( pxQueue->uxItemSize == ( UBaseType_t ) 0 )\r
{\r
#if ( configUSE_MUTEXES == 1 )\r
if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
{\r
/* The mutex is no longer being held. */\r
- vTaskPriorityDisinherit( ( void * ) pxQueue->pxMutexHolder );\r
- pxQueue->pxMutexHolder = NULL;\r
+ vTaskDecrementMutexHeldCount();\r
+ xReturn = xTaskPriorityDisinherit( ( void * ) pxQueue->pxMutexHolder );\r
+ pxQueue->pxMutexHolder = NULL; \r
}\r
else\r
{\r
}\r
\r
++( pxQueue->uxMessagesWaiting );\r
+\r
+ return xReturn;\r
}\r
/*-----------------------------------------------------------*/\r
\r
}\r
else\r
{\r
- mtCOVERAGE_TEST_MARKER();\r
+ /* A mutex was taken. */\r
+ vTaskIncrementMutexHeldCount();\r
}\r
}\r
/*-----------------------------------------------------------*/\r
if( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength )\r
{\r
traceQUEUE_SEND( pxQueueSetContainer );\r
- /* The data copies is the handle of the queue that contains data. */\r
- prvCopyDataToQueue( pxQueueSetContainer, &pxQueue, xCopyPosition );\r
+ /* The data copied is the handle of the queue that contains data. */\r
+ xReturn = prvCopyDataToQueue( pxQueueSetContainer, &pxQueue, xCopyPosition );\r
+\r
if( listLIST_IS_EMPTY( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) == pdFALSE )\r
{\r
if( xTaskRemoveFromEventList( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) != pdFALSE )\r