]> git.sur5r.net Git - freertos/commitdiff
Optimisations - being checked in for backup - not yet complete.
authorRichardBarry <RichardBarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Wed, 11 Mar 2009 10:53:45 +0000 (10:53 +0000)
committerRichardBarry <RichardBarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Wed, 11 Mar 2009 10:53:45 +0000 (10:53 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@703 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

Source/queue.c

index 6bd3350515bff340fa4d7cbc602651a845d84466..4f093f29e6bc1930ec146ad267109c9e5517aa88 100644 (file)
@@ -442,72 +442,11 @@ 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 = pdTRUE;\r
+signed portBASE_TYPE xEntryTimeSet = pdFALSE;\r
 xTimeOutType xTimeOut;\r
 \r
-       do\r
+       for( ;; )\r
        {\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
-                       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( 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
-                                       /* 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 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
-                               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
-               /* 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
@@ -516,7 +455,6 @@ xTimeOutType xTimeOut;
                        {\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
@@ -524,46 +462,74 @@ xTimeOutType xTimeOut;
                                {\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
+                                               /* The unblocked task has a priority higher than\r
+                                               our own so yield immediately. */\r
+                                               taskYIELD();\r
                                        }\r
                                }\r
+\r
+                               taskEXIT_CRITICAL();\r
+                               return pdPASS;\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
+                               if( xTicksToWait == ( portTickType ) 0 )\r
+                               {\r
+                                       taskEXIT_CRITICAL();\r
+                                       return errQUEUE_FULL;\r
+                               }\r
+                               else if( xEntryTimeSet == pdFALSE )\r
+                               {\r
+                                       vTaskSetTimeOutState( &xTimeOut );\r
+                                       xEntryTimeSet = pdTRUE;\r
+                               }\r
                        }\r
                }\r
-               taskEXIT_CRITICAL();\r
+               taskEXIT_CRITICAL();    \r
+\r
+               vTaskSuspendAll();\r
+               prvLockQueue( pxQueue );\r
 \r
-               if( xReturn == errQUEUE_FULL )\r
+               if( prvIsQueueFull( pxQueue ) )\r
                {\r
-                       if( xTicksToWait > ( portTickType ) 0 )\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( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
-                               {\r
-                                       xReturn = queueERRONEOUS_UNBLOCK;\r
-                               }\r
-                               else\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 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
-                                       traceQUEUE_SEND_FAILED( pxQueue );\r
+                                       taskYIELD();\r
                                }\r
                        }\r
                        else\r
                        {\r
-                               traceQUEUE_SEND_FAILED( pxQueue );\r
+                               prvUnlockQueue( pxQueue );\r
+                               ( void ) xTaskResumeAll();\r
+                               return errQUEUE_FULL;\r
                        }\r
                }\r
+               else\r
+               {\r
+                       prvUnlockQueue( pxQueue );\r
+                       ( void ) xTaskResumeAll();\r
+               }\r
        }\r
-       while( xReturn == queueERRONEOUS_UNBLOCK );\r
-\r
-       return xReturn;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -571,64 +537,19 @@ xTimeOutType xTimeOut;
 \r
        signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )\r
        {\r
-       signed portBASE_TYPE xReturn = pdPASS;\r
+       signed portBASE_TYPE xEntryTimeSet = pdFALSE;\r
        xTimeOutType xTimeOut;\r
 \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
-               do\r
+               for( ;; )\r
                {\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
-                               portENTER_CRITICAL();\r
-                               {\r
-                                       if( xReturn == pdPASS )\r
-                                       {\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( 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
+                               /* 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
                                        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
@@ -641,41 +562,48 @@ xTimeOutType xTimeOut;
                                                        taskYIELD();\r
                                                }\r
                                        }\r
+\r
+                                       taskEXIT_CRITICAL();\r
+                                       return pdPASS;\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
+                                       if( xTicksToWait == ( portTickType ) 0 )\r
+                                       {\r
+                                               taskEXIT_CRITICAL();\r
+                                               return errQUEUE_FULL;\r
+                                       }\r
+                                       else if( xEntryTimeSet == pdFALSE )\r
+                                       {\r
+                                               vTaskSetTimeOutState( &xTimeOut );\r
+                                               xEntryTimeSet = pdTRUE;\r
+                                       }\r
                                }\r
                        }\r
-                       taskEXIT_CRITICAL();\r
+                       taskEXIT_CRITICAL();    \r
 \r
-                       if( xReturn == errQUEUE_FULL )\r
+                       taskENTER_CRITICAL();\r
                        {\r
-                               if( xTicksToWait > ( portTickType ) 0 )\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
-                                               xReturn = queueERRONEOUS_UNBLOCK;\r
+                                               traceBLOCKING_ON_QUEUE_SEND( pxQueue );\r
+                                               vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );\r
+                                               taskYIELD();\r
                                        }\r
                                        else\r
                                        {\r
-                                               traceQUEUE_SEND_FAILED( pxQueue );\r
+                                               taskEXIT_CRITICAL();\r
+                                               return errQUEUE_FULL;\r
                                        }\r
                                }\r
-                               else\r
-                               {\r
-                                       traceQUEUE_SEND_FAILED( pxQueue );\r
-                               }\r
                        }\r
+                       taskEXIT_CRITICAL();\r
                }\r
-               while( xReturn == queueERRONEOUS_UNBLOCK );\r
-\r
-               return xReturn;\r
        }\r
 \r
 #endif /* configUSE_ALTERNATIVE_API */\r
@@ -685,58 +613,12 @@ xTimeOutType xTimeOut;
 \r
        signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )\r
        {\r
-       signed portBASE_TYPE xReturn = pdTRUE;\r
+       signed portBASE_TYPE xEntryTimeSet = pdFALSE;\r
        xTimeOutType xTimeOut;\r
        signed portCHAR *pcOriginalReadPosition;\r
 \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
-               do\r
+               for( ;; )\r
                {\r
-                       /* If there are no messages in the queue we may have to block. */\r
-                       if( xTicksToWait > ( portTickType ) 0 )\r
-                       {\r
-                               portENTER_CRITICAL();\r
-                               {\r
-                                       if( xReturn == pdPASS )\r
-                                       {\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
-                                                       traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );\r
-\r
-                                                       #if ( configUSE_MUTEXES == 1 )\r
-                                                       {\r
-                                                               if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
-                                                               {\r
-                                                                       vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );\r
-                                                               }\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
@@ -788,43 +670,66 @@ xTimeOutType xTimeOut;
                                                        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
+                                                               /* The task waiting has a higher priority than this task. */\r
                                                                taskYIELD();\r
                                                        }\r
                                                }\r
 \r
                                        }\r
 \r
-                                       xReturn = pdPASS;\r
+                                       taskEXIT_CRITICAL();\r
+                                       return pdPASS;\r
                                }\r
                                else\r
                                {\r
-                                       xReturn = errQUEUE_EMPTY;\r
+                                       if( xTicksToWait == ( portTickType ) 0 )\r
+                                       {\r
+                                               taskEXIT_CRITICAL();\r
+                                               return errQUEUE_EMPTY;\r
+                                       }\r
+                                       else if( xEntryTimeSet == pdFALSE )\r
+                                       {\r
+                                               vTaskSetTimeOutState( &xTimeOut );\r
+                                               xEntryTimeSet = pdTRUE;\r
+                                       }\r
                                }\r
                        }\r
                        taskEXIT_CRITICAL();\r
 \r
-                       if( xReturn == errQUEUE_EMPTY )\r
+                       taskENTER_CRITICAL();\r
                        {\r
-                               if( xTicksToWait > ( portTickType ) 0 )\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
-                                               xReturn = queueERRONEOUS_UNBLOCK;\r
+                                               traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );\r
+\r
+                                               #if ( configUSE_MUTEXES == 1 )\r
+                                               {\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
                                        else\r
                                        {\r
-                                               traceQUEUE_RECEIVE_FAILED( pxQueue );\r
+                                               taskEXIT_CRITICAL();\r
+                                               return errQUEUE_EMPTY;\r
                                        }\r
                                }\r
-                               else\r
-                               {\r
-                                       traceQUEUE_RECEIVE_FAILED( pxQueue );\r
-                               }\r
                        }\r
-               } while( xReturn == queueERRONEOUS_UNBLOCK );\r
-\r
-               return xReturn;\r
+                       taskEXIT_CRITICAL();\r
+               }\r
        }\r
 \r
 \r
@@ -886,66 +791,12 @@ unsigned portBASE_TYPE uxSavedInterruptStatus;
 \r
 signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )\r
 {\r
-signed portBASE_TYPE xReturn = pdTRUE;\r
+signed portBASE_TYPE xEntryTimeSet = pdFALSE;\r
 xTimeOutType xTimeOut;\r
 signed portCHAR *pcOriginalReadPosition;\r
 \r
-       do\r
+       for( ;; )\r
        {\r
-               /* If there are no messages in the queue we may have to block. */\r
-               if( xTicksToWait > ( portTickType ) 0 )\r
-               {\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
-                       /* 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_RECEIVE( pxQueue );\r
-\r
-                                       #if ( configUSE_MUTEXES == 1 )\r
-                                       {\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
-                                       prvUnlockQueue( pxQueue );\r
-                                       if( !xTaskResumeAll() )\r
-                                       {\r
-                                               taskYIELD();\r
-                                       }\r
-                               }\r
-                               else\r
-                               {\r
-                                       prvUnlockQueue( pxQueue );\r
-                                       ( void ) xTaskResumeAll();\r
-                               }\r
-                       }\r
-                       else\r
-                       {\r
-                               prvUnlockQueue( pxQueue );\r
-                               ( void ) xTaskResumeAll();\r
-                       }\r
-               }\r
-\r
                taskENTER_CRITICAL();\r
                {\r
                        if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
@@ -1004,37 +855,68 @@ signed portCHAR *pcOriginalReadPosition;
 \r
                                }\r
 \r
-                               xReturn = pdPASS;\r
+                               taskEXIT_CRITICAL();\r
+                               return pdPASS;\r
                        }\r
                        else\r
                        {\r
-                               xReturn = errQUEUE_EMPTY;\r
+                               if( xTicksToWait == ( portTickType ) 0 )\r
+                               {\r
+                                       taskEXIT_CRITICAL();\r
+                                       return errQUEUE_EMPTY;\r
+                               }\r
+                               else if( xEntryTimeSet == pdFALSE )\r
+                               {\r
+                                       vTaskSetTimeOutState( &xTimeOut );\r
+                                       xEntryTimeSet = pdTRUE;\r
+                               }\r
                        }\r
                }\r
                taskEXIT_CRITICAL();\r
 \r
-               if( xReturn == errQUEUE_EMPTY )\r
+               vTaskSuspendAll();\r
+               prvLockQueue( pxQueue );\r
+\r
+               if( prvIsQueueEmpty( pxQueue ) )\r
                {\r
-                       if( xTicksToWait > ( portTickType ) 0 )\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( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
+                               traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );\r
+\r
+                               #if ( configUSE_MUTEXES == 1 )\r
                                {\r
-                                       xReturn = queueERRONEOUS_UNBLOCK;\r
+                                       if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
+                                       {\r
+                                               portENTER_CRITICAL();\r
+                                                       vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );\r
+                                               portEXIT_CRITICAL();\r
+                                       }\r
                                }\r
-                               else\r
+                               #endif\r
+\r
+                               vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );\r
+                               prvUnlockQueue( pxQueue );\r
+                               if( !xTaskResumeAll() )\r
                                {\r
-                                       traceQUEUE_RECEIVE_FAILED( pxQueue );\r
+                                       taskYIELD();\r
                                }\r
                        }\r
                        else\r
                        {\r
-                               traceQUEUE_RECEIVE_FAILED( pxQueue );\r
+                               prvUnlockQueue( pxQueue );\r
+                               ( void ) xTaskResumeAll();\r
+                               return errQUEUE_EMPTY;\r
                        }\r
                }\r
-\r
-       } while( xReturn == queueERRONEOUS_UNBLOCK );\r
-\r
-       return xReturn;\r
+               else\r
+               {\r
+                       prvUnlockQueue( pxQueue );\r
+                       ( void ) xTaskResumeAll();\r
+               }\r
+       }\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r