]> git.sur5r.net Git - freertos/blobdiff - Source/queue.c
Update version numbers to V4.8.0
[freertos] / Source / queue.c
index 782408f271b37f94f02feed610b3664f363f68ab..5b9cf69e335455ea68629dd4ac9a9b2788a5e4cf 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.7.0 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.8.0 - Copyright (C) 2003-2008 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
        can be applied.\r
 \r
        ***************************************************************************\r
-       See http://www.FreeRTOS.org for documentation, latest information, license\r
-       and contact details.  Please ensure to read the configuration and relevant\r
-       port sections of the online documentation.\r
-\r
-       Also see http://www.SafeRTOS.com a version that has been certified for use\r
-       in safety critical systems, plus commercial licensing, development and\r
-       support options.\r
        ***************************************************************************\r
+       *                                                                                                                                                 *\r
+       * SAVE TIME AND MONEY!  Why not get us to quote to get FreeRTOS.org               *\r
+       * running on your hardware - or even write all or part of your application*\r
+       * for you?  See http://www.OpenRTOS.com for details.                                      *\r
+       *                                                                                                                                                 *\r
+       ***************************************************************************\r
+       ***************************************************************************\r
+\r
+       Please ensure to read the configuration and relevant port sections of the\r
+       online documentation.\r
+\r
+       http://www.FreeRTOS.org - Documentation, latest information, license and \r
+       contact details.\r
+\r
+       http://www.SafeRTOS.com - A version that is certified for use in safety \r
+       critical systems.\r
+\r
+       http://www.OpenRTOS.com - Commercial support, development, porting, \r
+       licensing and training services.\r
 */\r
 \r
 #include <stdlib.h>\r
@@ -101,7 +113,7 @@ typedef xQUEUE * xQueueHandle;
  */\r
 xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize );\r
 signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );\r
-unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue );\r
+unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle const pxQueue );\r
 void vQueueDelete( xQueueHandle xQueue );\r
 signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE xTaskPreviouslyWoken, portBASE_TYPE xCopyPosition );\r
 signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, const void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking );\r
@@ -112,6 +124,10 @@ portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlock
 portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex );\r
 signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );\r
 signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, const void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking );\r
+portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle const pxQueue );\r
+portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle const pxQueue );\r
+unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle const pxQueue );\r
+\r
 \r
 #if configUSE_CO_ROUTINES == 1\r
        signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken );\r
@@ -135,14 +151,14 @@ static void prvUnlockQueue( xQueueHandle pxQueue );
  *\r
  * @return pdTRUE if the queue contains no items, otherwise pdFALSE.\r
  */\r
-static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle pxQueue );\r
+static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle const pxQueue );\r
 \r
 /*\r
  * Uses a critical section to determine if there is any space in a queue.\r
  *\r
  * @return pdTRUE if there is no space, otherwise pdFALSE;\r
  */\r
-static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle pxQueue );\r
+static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle const pxQueue );\r
 \r
 /*\r
  * Copies an item into the queue, either at the front of the queue or the\r
@@ -207,10 +223,13 @@ size_t xQueueSizeInBytes;
                                vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) );\r
                                vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );\r
 \r
+                               traceQUEUE_CREATE( pxNewQueue );\r
+\r
                                return  pxNewQueue;\r
                        }\r
                        else\r
                        {\r
+                               traceQUEUE_CREATE_FAILED();\r
                                vPortFree( pxNewQueue );\r
                        }\r
                }\r
@@ -256,6 +275,12 @@ size_t xQueueSizeInBytes;
 \r
                        /* Start with the semaphore in the expected state. */\r
                        xQueueGenericSend( pxNewQueue, NULL, 0, queueSEND_TO_BACK );\r
+\r
+                       traceCREATE_MUTEX( pxNewQueue );\r
+               }\r
+               else\r
+               {\r
+                       traceCREATE_MUTEX_FAILED();\r
                }\r
        \r
                return pxNewQueue;\r
@@ -270,7 +295,7 @@ size_t xQueueSizeInBytes;
        {\r
        portBASE_TYPE xReturn;\r
 \r
-               /* If this is the task that holds the mutex then pxMutexHolder will not \r
+               /* If this is the task that holds the mutex then pxMutexHolder will not\r
                change outside of this task.  If this task does not hold the mutex then\r
                pxMutexHolder can never coincidentally equal the tasks handle, and as\r
                this is the only condition we are interested in it does not matter if\r
@@ -279,7 +304,7 @@ size_t xQueueSizeInBytes;
                if( pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle() )\r
                {\r
                        /* uxRecursiveCallCount cannot be zero if pxMutexHolder is equal to\r
-                       the task handle, therefore no underflow check is required.  Also, \r
+                       the task handle, therefore no underflow check is required.  Also,\r
                        uxRecursiveCallCount is only modified by the mutex holder, and as\r
                        there can only be one, no mutual exclusion is required to modify the\r
                        uxRecursiveCallCount member. */\r
@@ -294,11 +319,15 @@ size_t xQueueSizeInBytes;
                        }\r
 \r
                        xReturn = pdPASS;\r
+\r
+                       traceGIVE_MUTEX_RECURSIVE( pxMutex );\r
                }\r
                else\r
                {\r
                        /* We cannot give the mutex because we are not the holder. */\r
                        xReturn = pdFAIL;\r
+\r
+                       traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex );\r
                }\r
 \r
                return xReturn;\r
@@ -313,7 +342,7 @@ size_t xQueueSizeInBytes;
        {\r
        portBASE_TYPE xReturn;\r
 \r
-               /* Comments regarding mutual exclusion as per those within \r
+               /* Comments regarding mutual exclusion as per those within\r
                xQueueGiveMutexRecursive(). */\r
 \r
                if( pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle() )\r
@@ -333,6 +362,8 @@ size_t xQueueSizeInBytes;
                        }\r
                }\r
 \r
+               traceTAKE_MUTEX_RECURSIVE( pxMutex );\r
+\r
                return xReturn;\r
        }\r
 \r
@@ -341,7 +372,7 @@ size_t xQueueSizeInBytes;
 \r
 #if configUSE_COUNTING_SEMAPHORES == 1\r
 \r
-       xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount, portBASE_TYPE xIsRecursive )\r
+       xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount )\r
        {\r
        xQueueHandle pxHandle;\r
        \r
@@ -350,6 +381,12 @@ size_t xQueueSizeInBytes;
                if( pxHandle != NULL )\r
                {\r
                        pxHandle->uxMessagesWaiting = uxInitialCount;\r
+\r
+                       traceCREATE_COUNTING_SEMAPHORE();\r
+               }\r
+               else\r
+               {\r
+                       traceCREATE_COUNTING_SEMAPHORE_FAILED();\r
                }\r
 \r
                return pxHandle;\r
@@ -360,177 +397,127 @@ size_t xQueueSizeInBytes;
 \r
 signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )\r
 {\r
-signed portBASE_TYPE xReturn = pdPASS;\r
+signed portBASE_TYPE xReturn = pdTRUE;\r
 xTimeOutType xTimeOut;\r
 \r
-       /* Make sure other tasks do not access the queue. */\r
-       vTaskSuspendAll();\r
-\r
-       /* Capture the current time status for future reference. */\r
-       vTaskSetTimeOutState( &xTimeOut );\r
-\r
-       /* It is important that this is the only thread/ISR that modifies the\r
-       ready or delayed lists until xTaskResumeAll() is called.  Places where\r
-       the ready/delayed lists are modified include:\r
-\r
-               + vTaskDelay() -  Nothing can call vTaskDelay as the scheduler is\r
-                 suspended, vTaskDelay() cannot be called from an ISR.\r
-               + vTaskPrioritySet() - Has a critical section around the access.\r
-               + vTaskSwitchContext() - This will not get executed while the scheduler\r
-                 is suspended.\r
-               + prvCheckDelayedTasks() - This will not get executed while the\r
-                 scheduler is suspended.\r
-               + xTaskCreate() - Has a critical section around the access.\r
-               + vTaskResume() - Has a critical section around the access.\r
-               + xTaskResumeAll() - Has a critical section around the access.\r
-               + xTaskRemoveFromEventList - Checks to see if the scheduler is\r
-                 suspended.  If so then the TCB being removed from the event is\r
-                 removed from the event and added to the xPendingReadyList.\r
-       */\r
-\r
-       /* Make sure interrupts do not access the queue event list. */\r
-       prvLockQueue( pxQueue );\r
-\r
-       /* It is important that interrupts to not access the event list of the\r
-       queue being modified here.  Places where the event list is modified\r
-       include:\r
-\r
-               + xQueueGenericSendFromISR().  This checks the lock on the queue to see\r
-                 if it has access.  If the queue is locked then the Tx lock count is\r
-                 incremented to signify that a task waiting for data can be made ready\r
-                 once the queue lock is removed.  If the queue is not locked then\r
-                 a task can be moved from the event list, but will not be removed\r
-                 from the delayed list or placed in the ready list until the scheduler\r
-                 is unlocked.\r
-\r
-               + xQueueReceiveFromISR().  As per xQueueGenericSendFromISR().\r
-       */\r
-               \r
-       /* If the queue is already full we may have to block. */\r
        do\r
        {\r
-               if( prvIsQueueFull( pxQueue ) )\r
+       /* If xTicksToWait is zero then we are not going to block even\r
+       if there is no room in the queue to post. */\r
+               if( xTicksToWait > ( portTickType ) 0 )\r
                {\r
-                       /* The queue is full - do we want to block or just leave without\r
-                       posting? */\r
-                       if( xTicksToWait > ( portTickType ) 0 )\r
+                       vTaskSuspendAll();\r
+                       prvLockQueue( pxQueue );\r
+\r
+                       if( xReturn == pdTRUE )\r
                        {\r
-                               /* We are going to place ourselves on the xTasksWaitingToSend event\r
-                               list, and will get woken should the delay expire, or space become\r
-                               available on the queue.\r
-                               \r
-                               As detailed above we do not require mutual exclusion on the event\r
-                               list as nothing else can modify it or the ready lists while we\r
-                               have the scheduler suspended and queue locked.\r
-                               \r
-                               It is possible that an ISR has removed data from the queue since we\r
-                               checked if any was available.  If this is the case then the data\r
-                               will have been copied from the queue, and the queue variables\r
-                               updated, but the event list will not yet have been checked to see if\r
-                               anything is waiting as the queue is locked. */\r
-                               vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );\r
-       \r
-                               /* Force a context switch now as we are blocked.  We can do\r
-                               this from within a critical section as the task we are\r
-                               switching to has its own context.  When we return here (i.e. we\r
-                               unblock) we will leave the critical section as normal.\r
-                               \r
-                               It is possible that an ISR has caused an event on an unrelated and\r
-                               unlocked queue.  If this was the case then the event list for that\r
-                               queue will have been updated but the ready lists left unchanged -\r
-                               instead the readied task will have been added to the pending ready\r
-                               list. */\r
-                               taskENTER_CRITICAL();\r
+                               /* This is the first time through - we need to capture the\r
+                               time while the scheduler is locked to ensure we attempt to\r
+                               block at least once. */\r
+                               vTaskSetTimeOutState( &xTimeOut );\r
+                       }\r
+\r
+                       if( prvIsQueueFull( pxQueue ) )\r
+                       {\r
+                       /* Need to call xTaskCheckForTimeout again as time could\r
+                       have passed since it was last called if this is not the\r
+                       first time around this loop.  */\r
+                               if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
                                {\r
-                                       /* We can safely unlock the queue and scheduler here as\r
-                                       interrupts are disabled.  We must not yield with anything\r
-                                       locked, but we can yield from within a critical section.\r
-                                       \r
-                                       Tasks that have been placed on the pending ready list cannot\r
-                                       be tasks that are waiting for events on this queue.  See\r
-                                       in comment xTaskRemoveFromEventList(). */\r
+                                       traceBLOCKING_ON_QUEUE_SEND( pxQueue );\r
+                                       vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );\r
+                                               \r
+                                       /* Unlocking the queue means queue events can effect the\r
+                                       event list.  It is possible     that interrupts occurring now\r
+                                       remove this task from the event list again - but as the\r
+                                       scheduler is suspended the task will go onto the pending\r
+                                       ready last instead of the actual ready list. */\r
                                        prvUnlockQueue( pxQueue );\r
-       \r
-                                       /* Resuming the scheduler may cause a yield.  If so then there\r
-                                       is no point yielding again here. */\r
+                                               \r
+                                       /* Resuming the scheduler will move tasks from the pending\r
+                                       ready list into the ready list - so it is feasible that this\r
+                                       task is already in a ready list before it yields - in which\r
+                                       case the yield will not cause a context switch unless there\r
+                                       is also a higher priority task in the pending ready list. */\r
                                        if( !xTaskResumeAll() )\r
                                        {\r
                                                taskYIELD();\r
                                        }\r
-\r
-                                       /* We want to check to see if the queue is still full\r
-                                       before leaving the critical section.  This is to prevent\r
-                                       this task placing an item into the queue due to an\r
-                                       interrupt making space on the queue between critical\r
-                                       sections (when there might be a higher priority task\r
-                                       blocked on the queue that cannot run yet because the\r
-                                       scheduler gets suspended). */\r
-                                       if( pxQueue->uxMessagesWaiting == pxQueue->uxLength )\r
-                                       {\r
-                                               /* We unblocked but there is no space in the queue,\r
-                                               we probably timed out. */\r
-                                               xReturn = errQUEUE_FULL;\r
-                                       }\r
-       \r
-                                       /* Before leaving the critical section we have to ensure\r
-                                       exclusive access again. */\r
-                                       vTaskSuspendAll();\r
-                                       prvLockQueue( pxQueue );                                \r
                                }\r
-                               taskEXIT_CRITICAL();\r
+                               else\r
+                               {\r
+                                       prvUnlockQueue( pxQueue );\r
+                                       ( void ) xTaskResumeAll();\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                       /* The queue was not full so we can just unlock the\r
+                       scheduler and queue again before carrying on. */\r
+                               prvUnlockQueue( pxQueue );\r
+                               ( void ) xTaskResumeAll();\r
                        }\r
                }\r
-                       \r
-               /* If xReturn is errQUEUE_FULL then we unblocked when the queue\r
-               was still full.  Don't check it again now as it is possible that\r
-               an interrupt has removed an item from the queue since we left the\r
-               critical section and we don't want to write to the queue in case\r
-               there is a task of higher priority blocked waiting for space to\r
-               be available on the queue.  If this is the case the higher priority\r
-               task will execute when the scheduler is unsupended. */\r
-               if( xReturn != errQUEUE_FULL )\r
+                       \r
+               /* Higher priority tasks and interrupts can execute during\r
+               this time and could possible refill the queue - even if we\r
+               unblocked because space became available. */\r
+               \r
+               taskENTER_CRITICAL();\r
                {\r
-                       /* When we are here it is possible that we unblocked as space became\r
-                       available on the queue.  It is also possible that an ISR posted to the\r
-                       queue since we left the critical section, so it may be that again there\r
-                       is no space.  This would only happen if a task and ISR post onto the\r
-                       same queue. */\r
-                       taskENTER_CRITICAL();\r
+                       /* Is there room on the queue now?  To be running we must be\r
+                       the highest priority task wanting to access the queue. */\r
+                       if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
                        {\r
-                               if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
-                               {\r
-                                       /* There is room in the queue, copy the data into the queue. */                 \r
-                                       prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
-                                       xReturn = pdPASS;\r
-               \r
-                                       /* Update the TxLock count so prvUnlockQueue knows to check for\r
-                                       tasks waiting for data to become available in the queue. */\r
-                                       ++( pxQueue->xTxLock );\r
-                               }\r
-                               else\r
+                               traceQUEUE_SEND( pxQueue );\r
+                               prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
+                               xReturn = pdPASS;\r
+                                       \r
+                               /* If there was a task waiting for data to arrive on the\r
+                               queue then unblock it now. */\r
+                               if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
                                {\r
-                                       xReturn = errQUEUE_FULL;\r
+                                       if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )\r
+                                       {\r
+                                           /* The unblocked task has a priority higher than\r
+                                           our own so yield immediately. */\r
+                                           taskYIELD();\r
+                                       }\r
                                }\r
                        }\r
-                       taskEXIT_CRITICAL();\r
+                       else\r
+                       {\r
+                               /* Setting xReturn to errQUEUE_FULL will force its timeout\r
+                               to be re-evaluated.  This is necessary in case interrupts\r
+                               and higher priority tasks accessed the queue between this\r
+                               task being unblocked and subsequently attempting to write\r
+                               to the queue. */\r
+                               xReturn = errQUEUE_FULL;\r
+                       }\r
                }\r
+               taskEXIT_CRITICAL();\r
 \r
                if( xReturn == errQUEUE_FULL )\r
                {\r
-                       if( xTicksToWait > 0 )\r
+                       if( xTicksToWait > ( portTickType ) 0 )\r
                        {\r
                                if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
                                {\r
                                        xReturn = queueERRONEOUS_UNBLOCK;\r
                                }\r
+                               else\r
+                               {\r
+                                       traceQUEUE_SEND_FAILED( pxQueue );\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               traceQUEUE_SEND_FAILED( pxQueue );\r
                        }\r
                }\r
        }\r
        while( xReturn == queueERRONEOUS_UNBLOCK );\r
 \r
-       prvUnlockQueue( pxQueue );\r
-       xTaskResumeAll();\r
-\r
        return xReturn;\r
 }\r
 /*-----------------------------------------------------------*/\r
@@ -539,78 +526,109 @@ xTimeOutType xTimeOut;
 \r
        signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )\r
        {\r
-       signed portBASE_TYPE xReturn;\r
+       signed portBASE_TYPE xReturn = pdPASS;\r
        xTimeOutType xTimeOut;\r
 \r
-               /* The source code that implements the alternative (Alt) API is much \r
-               simpler because it executes everything from within a critical section.  \r
-               This is the approach taken by many other RTOSes, but FreeRTOS.org has the \r
-               preferred fully featured API too.  The fully featured API has more \r
-               complex code that takes longer to execute, but makes much less use of \r
-               critical sections.  Therefore the alternative API sacrifices interrupt \r
-               responsiveness to gain execution speed, whereas the fully featured API\r
-               sacrifices execution speed to ensure better interrupt responsiveness.  */\r
+               /* The source code that implements the alternative (Alt) API is\r
+               simpler because it makes more use of critical sections.  This is        \r
+               the approach taken by many other RTOSes, but FreeRTOS.org has the\r
+               preferred fully featured API too.  The fully featured API has more\r
+               complex code that takes longer to execute, but makes less use of\r
+               critical sections.  */\r
 \r
-               taskENTER_CRITICAL();\r
+               do\r
                {\r
-                       /* Capture the current time status for future reference. */\r
-                       vTaskSetTimeOutState( &xTimeOut );\r
-\r
-                       /* If the queue is already full we may have to block. */\r
-                       do\r
+               /* If xTicksToWait is zero then we are not going to block even\r
+               if there is no room in the queue to post. */\r
+                       if( xTicksToWait > ( portTickType ) 0 )\r
                        {\r
-                               if( pxQueue->uxMessagesWaiting == pxQueue->uxLength )\r
+                               portENTER_CRITICAL();\r
                                {\r
-                                       /* The queue is full - do we want to block or just leave without\r
-                                       posting? */\r
-                                       if( xTicksToWait > ( portTickType ) 0 )\r
+                                       if( xReturn == pdPASS )\r
                                        {\r
-                                               /* We are going to place ourselves on the xTasksWaitingToSend \r
-                                               event list, and will get woken should the delay expire, or \r
-                                               space become available on the queue. */\r
-                                               vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );\r
-                       \r
-                                               /* Force a context switch now as we are blocked.  We can do\r
-                                               this from within a critical section as the task we are\r
-                                               switching to has its own context.  When we return here (i.e.\r
-                                               we unblock) we will leave the critical section as normal. */\r
-                                               taskYIELD();\r
+                                               /* This is the first time through - capture the time\r
+                                               inside the critical section to ensure we attempt to\r
+                                               block at least once. */\r
+                                               vTaskSetTimeOutState( &xTimeOut );\r
                                        }\r
-                               }\r
                                        \r
+                                       if( prvIsQueueFull( pxQueue ) )\r
+                                       {\r
+                                       /* Need to call xTaskCheckForTimeout again as time could\r
+                                       have passed since it was last called if this is not the\r
+                                       first time around this loop.  */\r
+                                               if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
+                                               {\r
+                                                       traceBLOCKING_ON_QUEUE_SEND( pxQueue );\r
+                                                       vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );\r
+\r
+                                                       /* This will exit the critical section, then re-enter when\r
+                                                       the task next runs. */\r
+                                                       taskYIELD();\r
+                                               }\r
+                                       }\r
+                               }\r
+                               portEXIT_CRITICAL();\r
+                       }\r
+                               \r
+                       /* Higher priority tasks and interrupts can execute during\r
+                       this time and could possible refill the queue - even if we\r
+                       unblocked because space became available. */\r
+                       \r
+                       taskENTER_CRITICAL();\r
+                       {\r
+                               /* Is there room on the queue now?  To be running we must be\r
+                               the highest priority task wanting to access the queue. */\r
                                if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
                                {\r
-                                       /* There is room in the queue, copy the data into the queue. */                 \r
+                                       traceQUEUE_SEND( pxQueue );\r
                                        prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
                                        xReturn = pdPASS;\r
-\r
-                                       if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )\r
+                                               \r
+                                       /* If there was a task waiting for data to arrive on the\r
+                                       queue then unblock it now. */\r
+                                       if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
                                        {\r
-                                               if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
+                                               if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )\r
                                                {\r
-                                                       /* The task waiting has a higher priority. */\r
+                                                       /* The unblocked task has a priority higher than\r
+                                                       our own so yield immediately. */\r
                                                        taskYIELD();\r
                                                }\r
-                                       }                       \r
+                                       }\r
                                }\r
                                else\r
                                {\r
+                                       /* Setting xReturn to errQUEUE_FULL will force its timeout\r
+                                       to be re-evaluated.  This is necessary in case interrupts\r
+                                       and higher priority tasks accessed the queue between this\r
+                                       task being unblocked and subsequently attempting to write\r
+                                       to the queue. */\r
                                        xReturn = errQUEUE_FULL;\r
+                               }\r
+                       }\r
+                       taskEXIT_CRITICAL();\r
 \r
-                                       if( xTicksToWait > 0 )\r
-                                       {                                       \r
-                                               if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
-                                               {\r
-                                                       /* Another task must have accessed the queue between \r
-                                                       this task unblocking and actually executing. */\r
-                                                       xReturn = queueERRONEOUS_UNBLOCK;\r
-                                               }\r
+                       if( xReturn == errQUEUE_FULL )\r
+                       {\r
+                               if( xTicksToWait > ( portTickType ) 0 )\r
+                               {\r
+                                       if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
+                                       {\r
+                                               xReturn = queueERRONEOUS_UNBLOCK;\r
                                        }\r
+                                       else\r
+                                       {\r
+                                               traceQUEUE_SEND_FAILED( pxQueue );\r
+                                       }\r
+                               }\r
+                               else\r
+                               {\r
+                                       traceQUEUE_SEND_FAILED( pxQueue );\r
                                }\r
                        }\r
-                       while( xReturn == queueERRONEOUS_UNBLOCK );\r
                }\r
-               taskEXIT_CRITICAL();\r
+               while( xReturn == queueERRONEOUS_UNBLOCK );\r
 \r
                return xReturn;\r
        }\r
@@ -626,43 +644,58 @@ xTimeOutType xTimeOut;
        xTimeOutType xTimeOut;\r
        signed portCHAR *pcOriginalReadPosition;\r
 \r
-               /* The source code that implements the alternative (Alt) API is much \r
-               simpler because it executes everything from within a critical section.  \r
-               This is the approach taken by many other RTOSes, but FreeRTOS.org has the \r
-               preferred fully featured API too.  The fully featured API has more \r
-               complex code that takes longer to execute, but makes much less use of \r
-               critical sections.  Therefore the alternative API sacrifices interrupt \r
-               responsiveness to gain execution speed, whereas the fully featured API\r
-               sacrifices execution speed to ensure better interrupt responsiveness.  */\r
+               /* The source code that implements the alternative (Alt) API is\r
+               simpler because it makes more use of critical sections.  This is        \r
+               the approach taken by many other RTOSes, but FreeRTOS.org has the\r
+               preferred fully featured API too.  The fully featured API has more\r
+               complex code that takes longer to execute, but makes less use of\r
+               critical sections.  */\r
 \r
-               taskENTER_CRITICAL();\r
+               do\r
                {\r
-                       /* Capture the current time status for future reference. */\r
-                       vTaskSetTimeOutState( &xTimeOut );\r
-\r
-                       do\r
+                       /* If there are no messages in the queue we may have to block. */\r
+                       if( xTicksToWait > ( portTickType ) 0 )\r
                        {\r
-                               /* If there are no messages in the queue we may have to block. */\r
-                               if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 )\r
+                               portENTER_CRITICAL();\r
                                {\r
-                                       /* There are no messages in the queue, do we want to block or just\r
-                                       leave with nothing? */                  \r
-                                       if( xTicksToWait > ( portTickType ) 0 )\r
+                                       if( xReturn == pdPASS )\r
                                        {\r
-                                               #if ( configUSE_MUTEXES == 1 )\r
+                                               /* This is the first time through - capture the time\r
+                                               inside the critical section to ensure we attempt to\r
+                                               block at least once. */\r
+                                               vTaskSetTimeOutState( &xTimeOut );\r
+                                       }\r
+                                       \r
+                                       if( prvIsQueueEmpty( pxQueue ) )\r
+                                       {\r
+                                       /* Need to call xTaskCheckForTimeout again as time could\r
+                                       have passed since it was last called if this is not the\r
+                                       first time around this loop. */\r
+                                               if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
                                                {\r
-                                                       if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
+                                                       traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );\r
+\r
+                                                       #if ( configUSE_MUTEXES == 1 )\r
                                                        {\r
-                                                               vTaskPriorityInherit( ( void * const ) pxQueue->pxMutexHolder );\r
+                                                               if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
+                                                               {\r
+                                                                       portENTER_CRITICAL();\r
+                                                                               vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );\r
+                                                                       portEXIT_CRITICAL();\r
+                                                               }\r
                                                        }\r
+                                                       #endif\r
+\r
+                                                       vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );\r
+                                                       taskYIELD();\r
                                                }\r
-                                               #endif\r
-                                               \r
-                                               vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );\r
-                                               taskYIELD();\r
                                        }\r
                                }\r
-                       \r
+                               portEXIT_CRITICAL();\r
+                       }\r
+               \r
+                       taskENTER_CRITICAL();\r
+                       {\r
                                if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
                                {\r
                                        /* Remember our read position in case we are just peeking. */\r
@@ -672,9 +705,11 @@ xTimeOutType xTimeOut;
 \r
                                        if( xJustPeeking == pdFALSE )\r
                                        {\r
+                                               traceQUEUE_RECEIVE( pxQueue );\r
+\r
                                                /* We are actually removing data. */\r
                                                --( pxQueue->uxMessagesWaiting );\r
-                                                       \r
+\r
                                                #if ( configUSE_MUTEXES == 1 )\r
                                                {\r
                                                        if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
@@ -685,21 +720,36 @@ xTimeOutType xTimeOut;
                                                        }\r
                                                }\r
                                                #endif\r
-\r
-                                               if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )\r
+                                                       \r
+                                               if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
                                                {\r
-                                                       if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
+                                                       if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )\r
                                                        {\r
-                                                               /* The task waiting has a higher priority. */\r
                                                                taskYIELD();\r
                                                        }\r
                                                }\r
                                        }\r
                                        else\r
                                        {\r
+                                               traceQUEUE_PEEK( pxQueue );\r
+\r
                                                /* We are not removing the data, so reset our read\r
                                                pointer. */\r
                                                pxQueue->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 ) ) )\r
+                                               {\r
+                                                       /* Tasks that are removed from the event list will get added to\r
+                                                       the pending ready list as the scheduler is still suspended. */\r
+                                                       if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
+                                                       {\r
+                                                               /* The task waiting has a higher priority that this task. */\r
+                                                               taskYIELD();\r
+                                                       }\r
+                                               }                       \r
+\r
                                        }\r
                                        \r
                                        xReturn = pdPASS;                                       \r
@@ -707,23 +757,34 @@ xTimeOutType xTimeOut;
                                else\r
                                {\r
                                        xReturn = errQUEUE_EMPTY;\r
+                               }\r
+                       }\r
+                       taskEXIT_CRITICAL();\r
 \r
-                                       if( xTicksToWait > 0 )\r
+                       if( xReturn == errQUEUE_EMPTY )\r
+                       {\r
+                               if( xTicksToWait > ( portTickType ) 0 )\r
+                               {\r
+                                       if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
                                        {\r
-                                               if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
-                                               {\r
-                                                       xReturn = queueERRONEOUS_UNBLOCK;\r
-                                               }\r
+                                               xReturn = queueERRONEOUS_UNBLOCK;\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               traceQUEUE_RECEIVE_FAILED( pxQueue );\r
                                        }\r
                                }\r
-\r
-                       } while( xReturn == queueERRONEOUS_UNBLOCK );\r
-               }\r
-               taskEXIT_CRITICAL();\r
+                               else\r
+                               {\r
+                                       traceQUEUE_RECEIVE_FAILED( pxQueue );\r
+                               }\r
+                       }\r
+               } while( xReturn == queueERRONEOUS_UNBLOCK );\r
 \r
                return xReturn;\r
        }\r
 \r
+\r
 #endif /* configUSE_ALTERNATIVE_API */\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -736,6 +797,8 @@ signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void
        by this post). */\r
        if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
        {\r
+               traceQUEUE_SEND_FROM_ISR( pxQueue );\r
+\r
                prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
 \r
                /* If the queue is locked we do not alter the event list.  This will\r
@@ -764,6 +827,10 @@ signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void
                        ++( pxQueue->xTxLock );\r
                }\r
        }\r
+       else\r
+       {\r
+               traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue );\r
+       }\r
 \r
        return xTaskPreviouslyWoken;\r
 }\r
@@ -775,113 +842,128 @@ signed portBASE_TYPE xReturn = pdTRUE;
 xTimeOutType xTimeOut;\r
 signed portCHAR *pcOriginalReadPosition;\r
 \r
-       /* This function is very similar to xQueueGenericSend().  See comments\r
-       within xQueueGenericSend() for a more detailed explanation.\r
-\r
-       Make sure other tasks do not access the queue. */\r
-       vTaskSuspendAll();\r
-\r
-       /* Capture the current time status for future reference. */\r
-       vTaskSetTimeOutState( &xTimeOut );\r
-\r
-       /* Make sure interrupts do not access the queue. */\r
-       prvLockQueue( pxQueue );\r
-\r
        do\r
        {\r
                /* If there are no messages in the queue we may have to block. */\r
-               if( prvIsQueueEmpty( pxQueue ) )\r
+               if( xTicksToWait > ( portTickType ) 0 )\r
                {\r
-                       /* There are no messages in the queue, do we want to block or just\r
-                       leave with nothing? */                  \r
-                       if( xTicksToWait > ( portTickType ) 0 )\r
+                       vTaskSuspendAll();\r
+                       prvLockQueue( pxQueue );\r
+\r
+                       if( xReturn == pdTRUE )\r
+                       {\r
+                               /* This is the first time through - we need to capture the\r
+                               time while the scheduler is locked to ensure we attempt to\r
+                               block at least once. */\r
+                               vTaskSetTimeOutState( &xTimeOut );\r
+                       }\r
+\r
+                       if( prvIsQueueEmpty( pxQueue ) )\r
                        {\r
-                               #if ( configUSE_MUTEXES == 1 )\r
+                       /* Need to call xTaskCheckForTimeout again as time could\r
+                       have passed since it was last called if this is not the\r
+                       first time around this loop. */\r
+                               if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
                                {\r
-                                       if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
+                                       traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );\r
+\r
+                                       #if ( configUSE_MUTEXES == 1 )\r
                                        {\r
-                                               portENTER_CRITICAL();\r
-                                                       vTaskPriorityInherit( ( void * const ) pxQueue->pxMutexHolder );\r
-                                               portEXIT_CRITICAL();\r
+                                               if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
+                                               {\r
+                                                       portENTER_CRITICAL();\r
+                                                               vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );\r
+                                                       portEXIT_CRITICAL();\r
+                                               }\r
                                        }\r
-                               }\r
-                               #endif\r
-                               \r
-                               vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );\r
-                               taskENTER_CRITICAL();\r
-                               {\r
+                                       #endif\r
+\r
+                                       vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );\r
                                        prvUnlockQueue( pxQueue );\r
                                        if( !xTaskResumeAll() )\r
                                        {\r
                                                taskYIELD();\r
                                        }\r
-\r
-                                       if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 )\r
-                                       {\r
-                                               /* We unblocked but the queue is empty.  We probably\r
-                                               timed out. */\r
-                                               xReturn = errQUEUE_EMPTY;\r
-                                       }\r
-       \r
-                                       vTaskSuspendAll();\r
-                                       prvLockQueue( pxQueue );\r
                                }\r
-                               taskEXIT_CRITICAL();\r
+                               else\r
+                               {\r
+                                       prvUnlockQueue( pxQueue );\r
+                                       ( void ) xTaskResumeAll();\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               prvUnlockQueue( pxQueue );\r
+                               ( void ) xTaskResumeAll();\r
                        }\r
                }\r
        \r
-               if( xReturn != errQUEUE_EMPTY )\r
+               taskENTER_CRITICAL();\r
                {\r
-                       taskENTER_CRITICAL();\r
+                       if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
                        {\r
-                               if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
+                               /* Remember our read position in case we are just peeking. */\r
+                               pcOriginalReadPosition = pxQueue->pcReadFrom;\r
+\r
+                               prvCopyDataFromQueue( pxQueue, pvBuffer );\r
+\r
+                               if( xJustPeeking == pdFALSE )\r
                                {\r
-                                       /* Remember our read position in case we are just peeking. */\r
-                                       pcOriginalReadPosition = pxQueue->pcReadFrom;\r
+                                       traceQUEUE_RECEIVE( pxQueue );\r
 \r
-                                       prvCopyDataFromQueue( pxQueue, pvBuffer );\r
+                                       /* We are actually removing data. */\r
+                                       --( pxQueue->uxMessagesWaiting );\r
 \r
-                                       if( xJustPeeking == pdFALSE )\r
+                                       #if ( configUSE_MUTEXES == 1 )\r
                                        {\r
-                                               /* We are actually removing data. */\r
-                                               --( pxQueue->uxMessagesWaiting );\r
-                                                       \r
-                                               /* Increment the lock count so prvUnlockQueue knows to check for\r
-                                               tasks waiting for space to become available on the queue. */\r
-                                               ++( pxQueue->xRxLock );\r
-                                               \r
-                                               #if ( configUSE_MUTEXES == 1 )\r
+                                               if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\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 = xTaskGetCurrentTaskHandle();\r
-                                                       }\r
+                                                       /* Record the information required to implement\r
+                                                       priority inheritance should it become necessary. */\r
+                                                       pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle();\r
                                                }\r
-                                               #endif\r
                                        }\r
-                                       else\r
+                                       #endif\r
+                                               \r
+                                       if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
                                        {\r
-                                               /* We are not removing the data, so reset our read\r
-                                               pointer. */\r
-                                               pxQueue->pcReadFrom = pcOriginalReadPosition;\r
-\r
-                                               /* The data is being left in the queue, so increment the\r
-                                               lock count so prvUnlockQueue knows to check for other\r
-                                               tasks waiting for the data to be available. */\r
-                                               ++( pxQueue->xTxLock );                                         \r
+                                               if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )\r
+                                               {\r
+                                                       taskYIELD();\r
+                                               }\r
                                        }\r
-                                       \r
-                                       xReturn = pdPASS;                                       \r
                                }\r
                                else\r
                                {\r
-                                       xReturn = errQUEUE_EMPTY;\r
+                                       traceQUEUE_PEEK( pxQueue );\r
+\r
+                                       /* We are not removing the data, so reset our read\r
+                                       pointer. */\r
+                                       pxQueue->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 ) ) )\r
+                                       {\r
+                                               /* Tasks that are removed from the event list will get added to\r
+                                               the pending ready list as the scheduler is still suspended. */\r
+                                               if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
+                                               {\r
+                                                       /* The task waiting has a higher priority that this task. */\r
+                                                       taskYIELD();\r
+                                               }\r
+                                       }                       \r
+\r
                                }\r
+                               \r
+                               xReturn = pdPASS;                                       \r
+                       }\r
+                       else\r
+                       {\r
+                               xReturn = errQUEUE_EMPTY;\r
                        }\r
-                       taskEXIT_CRITICAL();\r
                }\r
+               taskEXIT_CRITICAL();\r
 \r
                if( xReturn == errQUEUE_EMPTY )\r
                {\r
@@ -891,14 +973,18 @@ signed portCHAR *pcOriginalReadPosition;
                                {\r
                                        xReturn = queueERRONEOUS_UNBLOCK;\r
                                }\r
+                               else\r
+                               {\r
+                                       traceQUEUE_RECEIVE_FAILED( pxQueue );\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               traceQUEUE_RECEIVE_FAILED( pxQueue );\r
                        }\r
                }\r
        } while( xReturn == queueERRONEOUS_UNBLOCK );\r
 \r
-       /* We no longer require exclusive access to the queue. */\r
-       prvUnlockQueue( pxQueue );\r
-       xTaskResumeAll();\r
-\r
        return xReturn;\r
 }\r
 /*-----------------------------------------------------------*/\r
@@ -910,6 +996,8 @@ signed portBASE_TYPE xReturn;
        /* We cannot block from an ISR, so check there is data available. */\r
        if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
        {\r
+               traceQUEUE_RECEIVE_FROM_ISR( pxQueue );\r
+\r
                prvCopyDataFromQueue( pxQueue, pvBuffer );\r
                --( pxQueue->uxMessagesWaiting );\r
 \r
@@ -945,13 +1033,14 @@ signed portBASE_TYPE xReturn;
        else\r
        {\r
                xReturn = pdFAIL;\r
+               traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue );\r
        }\r
 \r
        return xReturn;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue )\r
+unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle const pxQueue )\r
 {\r
 unsigned portBASE_TYPE uxReturn;\r
 \r
@@ -963,8 +1052,20 @@ unsigned portBASE_TYPE uxReturn;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue )\r
+{\r
+unsigned portBASE_TYPE uxReturn;\r
+\r
+       uxReturn = pxQueue->uxMessagesWaiting;\r
+\r
+       return uxReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
 void vQueueDelete( xQueueHandle pxQueue )\r
 {\r
+       traceQUEUE_DELETE( pxQueue );\r
+\r
        vPortFree( pxQueue->pcHead );\r
        vPortFree( pxQueue );\r
 }\r
@@ -979,7 +1080,7 @@ static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, port
                        if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
                        {\r
                                /* The mutex is no longer being held. */\r
-                               vTaskPriorityDisinherit( ( void * const ) pxQueue->pxMutexHolder );\r
+                               vTaskPriorityDisinherit( ( void * ) pxQueue->pxMutexHolder );\r
                 pxQueue->pxMutexHolder = NULL;\r
                        }\r
                }\r
@@ -1078,7 +1179,7 @@ static void prvUnlockQueue( xQueueHandle pxQueue )
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle pxQueue )\r
+static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle const pxQueue )\r
 {\r
 signed portBASE_TYPE xReturn;\r
 \r
@@ -1090,7 +1191,17 @@ signed portBASE_TYPE xReturn;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle pxQueue )\r
+signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue )\r
+{\r
+signed portBASE_TYPE xReturn;\r
+\r
+       xReturn = ( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 );\r
+\r
+       return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle const pxQueue )\r
 {\r
 signed portBASE_TYPE xReturn;\r
 \r
@@ -1102,6 +1213,16 @@ signed portBASE_TYPE xReturn;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue )\r
+{\r
+signed portBASE_TYPE xReturn;\r
+\r
+       xReturn = ( pxQueue->uxMessagesWaiting == pxQueue->uxLength );\r
+\r
+       return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
 #if configUSE_CO_ROUTINES == 1\r
 signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait )\r
 {\r