]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Source/queue.c
Update version number in preparation for maintenance release.
[freertos] / FreeRTOS / Source / queue.c
index d2a628db297583f0ad16a39eda35d4916ac29b1e..9fbe6ba983fe05456d6ae70a71d4f88a0244e2a0 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-    FreeRTOS V9.0.0rc2 - Copyright (C) 2016 Real Time Engineers Ltd.\r
+    FreeRTOS V9.0.1 - Copyright (C) 2017 Real Time Engineers Ltd.\r
     All rights reserved\r
 \r
     VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
@@ -255,6 +255,16 @@ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, const UBaseT
        static void prvInitialiseMutex( Queue_t *pxNewQueue ) PRIVILEGED_FUNCTION;\r
 #endif\r
 \r
+#if( configUSE_MUTEXES == 1 )\r
+       /*\r
+        * If a task waiting for a mutex causes the mutex holder to inherit a\r
+        * priority, but the waiting task times out, then the holder should\r
+        * disinherit the priority - but only down to the highest priority of any\r
+        * other tasks that are waiting for the same mutex.  This function returns\r
+        * that priority.\r
+        */\r
+       static UBaseType_t prvGetDisinheritPriorityAfterTimeout( const Queue_t * const pxQueue ) PRIVILEGED_FUNCTION;\r
+#endif\r
 /*-----------------------------------------------------------*/\r
 \r
 /*\r
@@ -567,6 +577,32 @@ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, const UBaseT
 #endif\r
 /*-----------------------------------------------------------*/\r
 \r
+#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) )\r
+\r
+       void* xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore )\r
+       {\r
+       void *pxReturn;\r
+\r
+               configASSERT( xSemaphore );\r
+\r
+               /* Mutexes cannot be used in interrupt service routines, so the mutex\r
+               holder should not change in an ISR, and therefore a critical section is\r
+               not required here. */\r
+               if( ( ( Queue_t * ) xSemaphore )->uxQueueType == queueQUEUE_IS_MUTEX )\r
+               {\r
+                       pxReturn = ( void * ) ( ( Queue_t * ) xSemaphore )->pxMutexHolder;\r
+               }\r
+               else\r
+               {\r
+                       pxReturn = NULL;\r
+               }\r
+\r
+               return pxReturn;\r
+       } /*lint !e818 xSemaphore cannot be a pointer to const because it is a typedef. */\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
 #if ( configUSE_RECURSIVE_MUTEXES == 1 )\r
 \r
        BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex )\r
@@ -643,7 +679,7 @@ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, const UBaseT
                }\r
                else\r
                {\r
-                       xReturn = xQueueGenericReceive( pxMutex, NULL, xTicksToWait, pdFALSE );\r
+                       xReturn = xQueueSemaphoreTake( pxMutex, xTicksToWait );\r
 \r
                        /* pdPASS will only be returned if the mutex was successfully\r
                        obtained.  The calling task may have entered the Blocked state\r
@@ -1052,7 +1088,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
                        {\r
                                /* Increment the lock count so the task that unlocks the queue\r
                                knows that data was posted while it was locked. */\r
-                               pxQueue->cTxLock = cTxLock + 1;\r
+                               pxQueue->cTxLock = ( int8_t ) ( cTxLock + 1 );\r
                        }\r
 \r
                        xReturn = pdPASS;\r
@@ -1127,7 +1163,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
                        can be assumed there is no mutex holder and no need to determine if\r
                        priority disinheritance is needed.  Simply increase the count of\r
                        messages (semaphores) available. */\r
-                       pxQueue->uxMessagesWaiting = uxMessagesWaiting + 1;\r
+                       pxQueue->uxMessagesWaiting = uxMessagesWaiting + ( UBaseType_t ) 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
@@ -1217,7 +1253,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
                        {\r
                                /* Increment the lock count so the task that unlocks the queue\r
                                knows that data was posted while it was locked. */\r
-                               pxQueue->cTxLock = cTxLock + 1;\r
+                               pxQueue->cTxLock = ( int8_t ) ( cTxLock + 1 );\r
                        }\r
 \r
                        xReturn = pdPASS;\r
@@ -1234,21 +1270,27 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-BaseType_t xQueueGenericReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait, const BaseType_t xJustPeeking )\r
+BaseType_t xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait )\r
 {\r
 BaseType_t xEntryTimeSet = pdFALSE;\r
 TimeOut_t xTimeOut;\r
-int8_t *pcOriginalReadPosition;\r
 Queue_t * const pxQueue = ( Queue_t * ) xQueue;\r
 \r
-       configASSERT( pxQueue );\r
-       configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) );\r
+       /* Check the pointer is not NULL. */\r
+       configASSERT( ( pxQueue ) );\r
+\r
+       /* The buffer into which data is received can only be NULL if the data size\r
+       is zero (so no data is copied into the buffer. */\r
+       configASSERT( !( ( ( pvBuffer ) == NULL ) && ( ( pxQueue )->uxItemSize != ( UBaseType_t ) 0U ) ) );\r
+\r
+       /* Cannot block if the scheduler is suspended. */\r
        #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )\r
        {\r
                configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );\r
        }\r
        #endif\r
 \r
+\r
        /* This function relaxes the coding standard somewhat to allow return\r
        statements within the function itself.  This is done in the interest\r
        of execution time efficiency. */\r
@@ -1263,44 +1305,19 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
                        must be the highest priority task wanting to access the queue. */\r
                        if( uxMessagesWaiting > ( UBaseType_t ) 0 )\r
                        {\r
-                               /* Remember the read position in case the queue is only being\r
-                               peeked. */\r
-                               pcOriginalReadPosition = pxQueue->u.pcReadFrom;\r
-\r
+                               /* Data available, remove one item. */\r
                                prvCopyDataFromQueue( pxQueue, pvBuffer );\r
+                               traceQUEUE_RECEIVE( pxQueue );\r
+                               pxQueue->uxMessagesWaiting = uxMessagesWaiting - ( UBaseType_t ) 1;\r
 \r
-                               if( xJustPeeking == pdFALSE )\r
+                               /* There is now space in the queue, were any tasks waiting to\r
+                               post to the queue?  If so, unblock the highest priority waiting\r
+                               task. */\r
+                               if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
                                {\r
-                                       traceQUEUE_RECEIVE( pxQueue );\r
-\r
-                                       /* Actually removing data, not just peeking. */\r
-                                       pxQueue->uxMessagesWaiting = uxMessagesWaiting - 1;\r
-\r
-                                       #if ( configUSE_MUTEXES == 1 )\r
-                                       {\r
-                                               if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
-                                               {\r
-                                                       /* Record the information required to implement\r
-                                                       priority inheritance should it become necessary. */\r
-                                                       pxQueue->pxMutexHolder = ( int8_t * ) pvTaskIncrementMutexHeldCount(); /*lint !e961 Cast is not redundant as TaskHandle_t is a typedef. */\r
-                                               }\r
-                                               else\r
-                                               {\r
-                                                       mtCOVERAGE_TEST_MARKER();\r
-                                               }\r
-                                       }\r
-                                       #endif /* configUSE_MUTEXES */\r
-\r
-                                       if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
+                                       if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
                                        {\r
-                                               if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
-                                               {\r
-                                                       queueYIELD_IF_USING_PREEMPTION();\r
-                                               }\r
-                                               else\r
-                                               {\r
-                                                       mtCOVERAGE_TEST_MARKER();\r
-                                               }\r
+                                               queueYIELD_IF_USING_PREEMPTION();\r
                                        }\r
                                        else\r
                                        {\r
@@ -1309,31 +1326,171 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
                                }\r
                                else\r
                                {\r
-                                       traceQUEUE_PEEK( pxQueue );\r
+                                       mtCOVERAGE_TEST_MARKER();\r
+                               }\r
+\r
+                               taskEXIT_CRITICAL();\r
+                               return pdPASS;\r
+                       }\r
+                       else\r
+                       {\r
+                               if( xTicksToWait == ( TickType_t ) 0 )\r
+                               {\r
+                                       /* The queue was empty and no block time is specified (or\r
+                                       the block time has expired) so leave now. */\r
+                                       taskEXIT_CRITICAL();\r
+                                       traceQUEUE_RECEIVE_FAILED( pxQueue );\r
+                                       return errQUEUE_EMPTY;\r
+                               }\r
+                               else if( xEntryTimeSet == pdFALSE )\r
+                               {\r
+                                       /* The queue was empty and a block time was specified so\r
+                                       configure the timeout structure. */\r
+                                       vTaskSetTimeOutState( &xTimeOut );\r
+                                       xEntryTimeSet = pdTRUE;\r
+                               }\r
+                               else\r
+                               {\r
+                                       /* Entry time was already set. */\r
+                                       mtCOVERAGE_TEST_MARKER();\r
+                               }\r
+                       }\r
+               }\r
+               taskEXIT_CRITICAL();\r
 \r
-                                       /* The data is not being removed, so reset the read\r
-                                       pointer. */\r
-                                       pxQueue->u.pcReadFrom = pcOriginalReadPosition;\r
+               /* Interrupts and other tasks can send to and receive from the queue\r
+               now the critical section has been exited. */\r
 \r
-                                       /* The data is being left in the queue, so see if there are\r
-                                       any other tasks waiting for the data. */\r
-                                       if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
+               vTaskSuspendAll();\r
+               prvLockQueue( pxQueue );\r
+\r
+               /* Update the timeout state to see if it has expired yet. */\r
+               if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
+               {\r
+                       /* The timeout has not expired.  If the queue is still empty place\r
+                       the task on the list of tasks waiting to receive from the queue. */\r
+                       if( prvIsQueueEmpty( pxQueue ) != pdFALSE )\r
+                       {\r
+                               traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );\r
+                               vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );\r
+                               prvUnlockQueue( pxQueue );\r
+                               if( xTaskResumeAll() == pdFALSE )\r
+                               {\r
+                                       portYIELD_WITHIN_API();\r
+                               }\r
+                               else\r
+                               {\r
+                                       mtCOVERAGE_TEST_MARKER();\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               /* The queue contains data again.  Loop back to try and read the\r
+                               data. */\r
+                               prvUnlockQueue( pxQueue );\r
+                               ( void ) xTaskResumeAll();\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       /* Timed out.  If there is no data in the queue exit, otherwise loop\r
+                       back and attempt to read the data. */\r
+                       prvUnlockQueue( pxQueue );\r
+                       ( void ) xTaskResumeAll();\r
+\r
+                       if( prvIsQueueEmpty( pxQueue ) != pdFALSE )\r
+                       {\r
+                               traceQUEUE_RECEIVE_FAILED( pxQueue );\r
+                               return errQUEUE_EMPTY;\r
+                       }\r
+                       else\r
+                       {\r
+                               mtCOVERAGE_TEST_MARKER();\r
+                       }\r
+               }\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait )\r
+{\r
+BaseType_t xEntryTimeSet = pdFALSE;\r
+TimeOut_t xTimeOut;\r
+Queue_t * const pxQueue = ( Queue_t * ) xQueue;\r
+\r
+#if( configUSE_MUTEXES == 1 )\r
+       BaseType_t xInheritanceOccurred = pdFALSE;\r
+#endif\r
+\r
+       /* Check the queue pointer is not NULL. */\r
+       configASSERT( ( pxQueue ) );\r
+\r
+       /* Check this really is a semaphore, in which case the item size will be\r
+       0. */\r
+       configASSERT( pxQueue->uxItemSize == 0 );\r
+\r
+       /* Cannot block if the scheduler is suspended. */\r
+       #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )\r
+       {\r
+               configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );\r
+       }\r
+       #endif\r
+\r
+\r
+       /* This function relaxes the coding standard somewhat to allow return\r
+       statements within the function itself.  This is done in the interest\r
+       of execution time efficiency. */\r
+\r
+       for( ;; )\r
+       {\r
+               taskENTER_CRITICAL();\r
+               {\r
+                       /* Semaphores are queues with an item size of 0, and where the\r
+                       number of messages in the queue is the semaphore's count value. */\r
+                       const UBaseType_t uxSemaphoreCount = pxQueue->uxMessagesWaiting;\r
+\r
+                       /* Is there data in the queue now?  To be running the calling task\r
+                       must be the highest priority task wanting to access the queue. */\r
+                       if( uxSemaphoreCount > ( UBaseType_t ) 0 )\r
+                       {\r
+                               traceQUEUE_RECEIVE( pxQueue );\r
+\r
+                               /* Semaphores are queues with a data size of zero and where the\r
+                               messages waiting is the semaphore's count.  Reduce the count. */\r
+                               pxQueue->uxMessagesWaiting = uxSemaphoreCount - ( UBaseType_t ) 1;\r
+\r
+                               #if ( configUSE_MUTEXES == 1 )\r
+                               {\r
+                                       if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
                                        {\r
-                                               if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
-                                               {\r
-                                                       /* The task waiting has a higher priority than this task. */\r
-                                                       queueYIELD_IF_USING_PREEMPTION();\r
-                                               }\r
-                                               else\r
-                                               {\r
-                                                       mtCOVERAGE_TEST_MARKER();\r
-                                               }\r
+                                               /* Record the information required to implement\r
+                                               priority inheritance should it become necessary. */\r
+                                               pxQueue->pxMutexHolder = ( int8_t * ) pvTaskIncrementMutexHeldCount(); /*lint !e961 Cast is not redundant as TaskHandle_t is a typedef. */\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               mtCOVERAGE_TEST_MARKER();\r
+                                       }\r
+                               }\r
+                               #endif /* configUSE_MUTEXES */\r
+\r
+                               /* Check to see if other tasks are blocked waiting to give the\r
+                               semaphore, and if so, unblock the highest priority such task. */\r
+                               if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
+                               {\r
+                                       if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
+                                       {\r
+                                               queueYIELD_IF_USING_PREEMPTION();\r
                                        }\r
                                        else\r
                                        {\r
                                                mtCOVERAGE_TEST_MARKER();\r
                                        }\r
                                }\r
+                               else\r
+                               {\r
+                                       mtCOVERAGE_TEST_MARKER();\r
+                               }\r
 \r
                                taskEXIT_CRITICAL();\r
                                return pdPASS;\r
@@ -1342,16 +1499,21 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
                        {\r
                                if( xTicksToWait == ( TickType_t ) 0 )\r
                                {\r
-                                       /* The queue was empty and no block time is specified (or\r
-                                       the block time has expired) so leave now. */\r
+                                       /* For inheritance to have occurred there must have been an\r
+                                       initial timeout, and an adjusted timeout cannot become 0, as\r
+                                       if it were 0 the function would have exited. */\r
+                                       configASSERT( xInheritanceOccurred == pdFALSE );\r
+\r
+                                       /* The semaphore count was 0 and no block time is specified\r
+                                       (or the block time has expired) so exit now. */\r
                                        taskEXIT_CRITICAL();\r
                                        traceQUEUE_RECEIVE_FAILED( pxQueue );\r
                                        return errQUEUE_EMPTY;\r
                                }\r
                                else if( xEntryTimeSet == pdFALSE )\r
                                {\r
-                                       /* The queue was empty and a block time was specified so\r
-                                       configure the timeout structure. */\r
+                                       /* The semaphore count was 0 and a block time was specified\r
+                                       so configure the timeout structure ready to block. */\r
                                        vTaskSetTimeOutState( &xTimeOut );\r
                                        xEntryTimeSet = pdTRUE;\r
                                }\r
@@ -1364,7 +1526,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
                }\r
                taskEXIT_CRITICAL();\r
 \r
-               /* Interrupts and other tasks can send to and receive from the queue\r
+               /* Interrupts and other tasks can give to and take from the semaphore\r
                now the critical section has been exited. */\r
 \r
                vTaskSuspendAll();\r
@@ -1373,6 +1535,10 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
                /* Update the timeout state to see if it has expired yet. */\r
                if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
                {\r
+                       /* A block time is specified and not expired.  If the semaphore\r
+                       count is 0 then enter the Blocked state to wait for a semaphore to\r
+                       become available.  As semaphores are implemented with queues the\r
+                       queue being empty is equivalent to the semaphore count being 0. */\r
                        if( prvIsQueueEmpty( pxQueue ) != pdFALSE )\r
                        {\r
                                traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );\r
@@ -1383,7 +1549,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
                                        {\r
                                                taskENTER_CRITICAL();\r
                                                {\r
-                                                       vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );\r
+                                                       xInheritanceOccurred = xTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );\r
                                                }\r
                                                taskEXIT_CRITICAL();\r
                                        }\r
@@ -1407,13 +1573,193 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
                        }\r
                        else\r
                        {\r
-                               /* Try again. */\r
+                               /* There was no timeout and the semaphore count was not 0, so\r
+                               attempt to take the semaphore again. */\r
                                prvUnlockQueue( pxQueue );\r
                                ( void ) xTaskResumeAll();\r
                        }\r
                }\r
                else\r
                {\r
+                       /* Timed out. */\r
+                       prvUnlockQueue( pxQueue );\r
+                       ( void ) xTaskResumeAll();\r
+\r
+                       /* If the semaphore count is 0 exit now as the timeout has\r
+                       expired.  Otherwise return to attempt to take the semaphore that is\r
+                       known to be available.  As semaphores are implemented by queues the\r
+                       queue being empty is equivalent to the semaphore count being 0. */\r
+                       if( prvIsQueueEmpty( pxQueue ) != pdFALSE )\r
+                       {\r
+                               #if ( configUSE_MUTEXES == 1 )\r
+                               {\r
+                                       /* xInheritanceOccurred could only have be set if\r
+                                       pxQueue->uxQueueType == queueQUEUE_IS_MUTEX so no need to\r
+                                       test the mutex type again to check it is actually a mutex. */\r
+                                       if( xInheritanceOccurred != pdFALSE )\r
+                                       {\r
+                                               taskENTER_CRITICAL();\r
+                                               {\r
+                                                       UBaseType_t uxHighestWaitingPriority;\r
+\r
+                                                       /* This task blocking on the mutex caused another\r
+                                                       task to inherit this task's priority.  Now this task\r
+                                                       has timed out the priority should be disinherited\r
+                                                       again, but only as low as the next highest priority\r
+                                                       task that is waiting for the same mutex. */\r
+                                                       uxHighestWaitingPriority = prvGetDisinheritPriorityAfterTimeout( pxQueue );\r
+                                                       vTaskPriorityDisinheritAfterTimeout( ( void * ) pxQueue->pxMutexHolder, uxHighestWaitingPriority );\r
+                                               }\r
+                                               taskEXIT_CRITICAL();\r
+                                       }\r
+                               }\r
+                               #endif /* configUSE_MUTEXES */\r
+\r
+                               traceQUEUE_RECEIVE_FAILED( pxQueue );\r
+                               return errQUEUE_EMPTY;\r
+                       }\r
+                       else\r
+                       {\r
+                               mtCOVERAGE_TEST_MARKER();\r
+                       }\r
+               }\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+BaseType_t xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait )\r
+{\r
+BaseType_t xEntryTimeSet = pdFALSE;\r
+TimeOut_t xTimeOut;\r
+int8_t *pcOriginalReadPosition;\r
+Queue_t * const pxQueue = ( Queue_t * ) xQueue;\r
+\r
+       /* Check the pointer is not NULL. */\r
+       configASSERT( ( pxQueue ) );\r
+\r
+       /* The buffer into which data is received can only be NULL if the data size\r
+       is zero (so no data is copied into the buffer. */\r
+       configASSERT( !( ( ( pvBuffer ) == NULL ) && ( ( pxQueue )->uxItemSize != ( UBaseType_t ) 0U ) ) );\r
+\r
+       /* Cannot block if the scheduler is suspended. */\r
+       #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )\r
+       {\r
+               configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );\r
+       }\r
+       #endif\r
+\r
+\r
+       /* This function relaxes the coding standard somewhat to allow return\r
+       statements within the function itself.  This is done in the interest\r
+       of execution time efficiency. */\r
+\r
+       for( ;; )\r
+       {\r
+               taskENTER_CRITICAL();\r
+               {\r
+                       const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting;\r
+\r
+                       /* Is there data in the queue now?  To be running the calling task\r
+                       must be the highest priority task wanting to access the queue. */\r
+                       if( uxMessagesWaiting > ( UBaseType_t ) 0 )\r
+                       {\r
+                               /* Remember the read position so it can be reset after the data\r
+                               is read from the queue as this function is only peeking the\r
+                               data, not removing it. */\r
+                               pcOriginalReadPosition = pxQueue->u.pcReadFrom;\r
+\r
+                               prvCopyDataFromQueue( pxQueue, pvBuffer );\r
+                               traceQUEUE_PEEK( pxQueue );\r
+\r
+                               /* The data is not being removed, so reset the read pointer. */\r
+                               pxQueue->u.pcReadFrom = pcOriginalReadPosition;\r
+\r
+                               /* The data is being left in the queue, so see if there are\r
+                               any other tasks waiting for the data. */\r
+                               if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
+                               {\r
+                                       if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
+                                       {\r
+                                               /* The task waiting has a higher priority than this task. */\r
+                                               queueYIELD_IF_USING_PREEMPTION();\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               mtCOVERAGE_TEST_MARKER();\r
+                                       }\r
+                               }\r
+                               else\r
+                               {\r
+                                       mtCOVERAGE_TEST_MARKER();\r
+                               }\r
+\r
+                               taskEXIT_CRITICAL();\r
+                               return pdPASS;\r
+                       }\r
+                       else\r
+                       {\r
+                               if( xTicksToWait == ( TickType_t ) 0 )\r
+                               {\r
+                                       /* The queue was empty and no block time is specified (or\r
+                                       the block time has expired) so leave now. */\r
+                                       taskEXIT_CRITICAL();\r
+                                       traceQUEUE_RECEIVE_FAILED( pxQueue );\r
+                                       return errQUEUE_EMPTY;\r
+                               }\r
+                               else if( xEntryTimeSet == pdFALSE )\r
+                               {\r
+                                       /* The queue was empty and a block time was specified so\r
+                                       configure the timeout structure ready to enter the blocked\r
+                                       state. */\r
+                                       vTaskSetTimeOutState( &xTimeOut );\r
+                                       xEntryTimeSet = pdTRUE;\r
+                               }\r
+                               else\r
+                               {\r
+                                       /* Entry time was already set. */\r
+                                       mtCOVERAGE_TEST_MARKER();\r
+                               }\r
+                       }\r
+               }\r
+               taskEXIT_CRITICAL();\r
+\r
+               /* Interrupts and other tasks can send to and receive from the queue\r
+               now the critical section has been exited. */\r
+\r
+               vTaskSuspendAll();\r
+               prvLockQueue( pxQueue );\r
+\r
+               /* Update the timeout state to see if it has expired yet. */\r
+               if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
+               {\r
+                       /* Timeout has not expired yet, check to see if there is data in the\r
+                       queue now, and if not enter the Blocked state to wait for data. */\r
+                       if( prvIsQueueEmpty( pxQueue ) != pdFALSE )\r
+                       {\r
+                               traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );\r
+                               vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );\r
+                               prvUnlockQueue( pxQueue );\r
+                               if( xTaskResumeAll() == pdFALSE )\r
+                               {\r
+                                       portYIELD_WITHIN_API();\r
+                               }\r
+                               else\r
+                               {\r
+                                       mtCOVERAGE_TEST_MARKER();\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               /* There is data in the queue now, so don't enter the blocked\r
+                               state, instead return to try and obtain the data. */\r
+                               prvUnlockQueue( pxQueue );\r
+                               ( void ) xTaskResumeAll();\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       /* The timeout has expired.  If there is still no data in the queue\r
+                       exit, otherwise go back and try to read the data again. */\r
                        prvUnlockQueue( pxQueue );\r
                        ( void ) xTaskResumeAll();\r
 \r
@@ -1468,7 +1814,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
                        traceQUEUE_RECEIVE_FROM_ISR( pxQueue );\r
 \r
                        prvCopyDataFromQueue( pxQueue, pvBuffer );\r
-                       pxQueue->uxMessagesWaiting = uxMessagesWaiting - 1;\r
+                       pxQueue->uxMessagesWaiting = uxMessagesWaiting - ( UBaseType_t ) 1;\r
 \r
                        /* If the queue is locked the event list will not be modified.\r
                        Instead update the lock count so the task that unlocks the queue\r
@@ -1505,7 +1851,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
                        {\r
                                /* Increment the lock count so the task that unlocks the queue\r
                                knows that data was removed while it was locked. */\r
-                               pxQueue->cRxLock = cRxLock + 1;\r
+                               pxQueue->cRxLock = ( int8_t ) ( cRxLock + 1 );\r
                        }\r
 \r
                        xReturn = pdPASS;\r
@@ -1654,6 +2000,12 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
                        mtCOVERAGE_TEST_MARKER();\r
                }\r
        }\r
+       #else\r
+       {\r
+               /* The queue must have been statically allocated, so is not going to be\r
+               deleted.  Avoid compiler warnings about the unused parameter. */\r
+               ( void ) pxQueue;\r
+       }\r
        #endif /* configSUPPORT_DYNAMIC_ALLOCATION */\r
 }\r
 /*-----------------------------------------------------------*/\r
@@ -1688,6 +2040,33 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
 #endif /* configUSE_TRACE_FACILITY */\r
 /*-----------------------------------------------------------*/\r
 \r
+#if( configUSE_MUTEXES == 1 )\r
+\r
+       static UBaseType_t prvGetDisinheritPriorityAfterTimeout( const Queue_t * const pxQueue )\r
+       {\r
+       UBaseType_t uxHighestPriorityOfWaitingTasks;\r
+\r
+               /* If a task waiting for a mutex causes the mutex holder to inherit a\r
+               priority, but the waiting task times out, then the holder should\r
+               disinherit the priority - but only down to the highest priority of any\r
+               other tasks that are waiting for the same mutex.  For this purpose,\r
+               return the priority of the highest priority task that is waiting for the\r
+               mutex. */\r
+               if( listCURRENT_LIST_LENGTH( &( pxQueue->xTasksWaitingToReceive ) ) > 0 )\r
+               {\r
+                       uxHighestPriorityOfWaitingTasks = configMAX_PRIORITIES - listGET_ITEM_VALUE_OF_HEAD_ENTRY( &( pxQueue->xTasksWaitingToReceive ) );\r
+               }\r
+               else\r
+               {\r
+                       uxHighestPriorityOfWaitingTasks = tskIDLE_PRIORITY;\r
+               }\r
+\r
+               return uxHighestPriorityOfWaitingTasks;\r
+       }\r
+\r
+#endif /* configUSE_MUTEXES */\r
+/*-----------------------------------------------------------*/\r
+\r
 static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, const void *pvItemToQueue, const BaseType_t xPosition )\r
 {\r
 BaseType_t xReturn = pdFALSE;\r
@@ -1761,7 +2140,7 @@ UBaseType_t uxMessagesWaiting;
                }\r
        }\r
 \r
-       pxQueue->uxMessagesWaiting = uxMessagesWaiting + 1;\r
+       pxQueue->uxMessagesWaiting = uxMessagesWaiting + ( UBaseType_t ) 1;\r
 \r
        return xReturn;\r
 }\r
@@ -2310,7 +2689,7 @@ BaseType_t xReturn;
                }\r
 \r
                return pcReturn;\r
-       }\r
+       } /*lint !e818 xQueue cannot be a pointer to const because it is a typedef. */\r
 \r
 #endif /* configQUEUE_REGISTRY_SIZE */\r
 /*-----------------------------------------------------------*/\r
@@ -2389,7 +2768,7 @@ BaseType_t xReturn;
        {\r
        QueueSetHandle_t pxQueue;\r
 \r
-               pxQueue = xQueueGenericCreate( uxEventQueueLength, sizeof( Queue_t * ), queueQUEUE_TYPE_SET );\r
+               pxQueue = xQueueGenericCreate( uxEventQueueLength, ( UBaseType_t ) sizeof( Queue_t * ), queueQUEUE_TYPE_SET );\r
 \r
                return pxQueue;\r
        }\r
@@ -2472,7 +2851,7 @@ BaseType_t xReturn;
        {\r
        QueueSetMemberHandle_t xReturn = NULL;\r
 \r
-               ( void ) xQueueGenericReceive( ( QueueHandle_t ) xQueueSet, &xReturn, xTicksToWait, pdFALSE ); /*lint !e961 Casting from one typedef to another is not redundant. */\r
+               ( void ) xQueueReceive( ( QueueHandle_t ) xQueueSet, &xReturn, xTicksToWait ); /*lint !e961 Casting from one typedef to another is not redundant. */\r
                return xReturn;\r
        }\r
 \r
@@ -2534,7 +2913,7 @@ BaseType_t xReturn;
                        }\r
                        else\r
                        {\r
-                               pxQueueSetContainer->cTxLock = cTxLock + 1;\r
+                               pxQueueSetContainer->cTxLock = ( int8_t ) ( cTxLock + 1 );\r
                        }\r
                }\r
                else\r