mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-20 05:21:59 -04:00
Optimisations - being checked in for backup - not yet complete.
This commit is contained in:
parent
dae13395ed
commit
aaeb4790de
438
Source/queue.c
438
Source/queue.c
|
@ -442,26 +442,54 @@ size_t xQueueSizeInBytes;
|
||||||
|
|
||||||
signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
|
signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
|
||||||
{
|
{
|
||||||
signed portBASE_TYPE xReturn = pdTRUE;
|
signed portBASE_TYPE xEntryTimeSet = pdFALSE;
|
||||||
xTimeOutType xTimeOut;
|
xTimeOutType xTimeOut;
|
||||||
|
|
||||||
do
|
for( ;; )
|
||||||
{
|
{
|
||||||
/* If xTicksToWait is zero then we are not going to block even
|
taskENTER_CRITICAL();
|
||||||
if there is no room in the queue to post. */
|
|
||||||
if( xTicksToWait > ( portTickType ) 0 )
|
|
||||||
{
|
{
|
||||||
|
/* Is there room on the queue now? To be running we must be
|
||||||
|
the highest priority task wanting to access the queue. */
|
||||||
|
if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
|
||||||
|
{
|
||||||
|
traceQUEUE_SEND( pxQueue );
|
||||||
|
prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
|
||||||
|
|
||||||
|
/* If there was a task waiting for data to arrive on the
|
||||||
|
queue then unblock it now. */
|
||||||
|
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
|
||||||
|
{
|
||||||
|
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )
|
||||||
|
{
|
||||||
|
/* The unblocked task has a priority higher than
|
||||||
|
our own so yield immediately. */
|
||||||
|
taskYIELD();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
return pdPASS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( xTicksToWait == ( portTickType ) 0 )
|
||||||
|
{
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
return errQUEUE_FULL;
|
||||||
|
}
|
||||||
|
else if( xEntryTimeSet == pdFALSE )
|
||||||
|
{
|
||||||
|
vTaskSetTimeOutState( &xTimeOut );
|
||||||
|
xEntryTimeSet = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
vTaskSuspendAll();
|
vTaskSuspendAll();
|
||||||
prvLockQueue( pxQueue );
|
prvLockQueue( pxQueue );
|
||||||
|
|
||||||
if( xReturn == pdTRUE )
|
|
||||||
{
|
|
||||||
/* This is the first time through - we need to capture the
|
|
||||||
time while the scheduler is locked to ensure we attempt to
|
|
||||||
block at least once. */
|
|
||||||
vTaskSetTimeOutState( &xTimeOut );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( prvIsQueueFull( pxQueue ) )
|
if( prvIsQueueFull( pxQueue ) )
|
||||||
{
|
{
|
||||||
/* Need to call xTaskCheckForTimeout again as time could
|
/* Need to call xTaskCheckForTimeout again as time could
|
||||||
|
@ -493,21 +521,27 @@ xTimeOutType xTimeOut;
|
||||||
{
|
{
|
||||||
prvUnlockQueue( pxQueue );
|
prvUnlockQueue( pxQueue );
|
||||||
( void ) xTaskResumeAll();
|
( void ) xTaskResumeAll();
|
||||||
|
return errQUEUE_FULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* The queue was not full so we can just unlock the
|
|
||||||
scheduler and queue again before carrying on. */
|
|
||||||
prvUnlockQueue( pxQueue );
|
prvUnlockQueue( pxQueue );
|
||||||
( void ) xTaskResumeAll();
|
( void ) xTaskResumeAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Higher priority tasks and interrupts can execute during
|
#if configUSE_ALTERNATIVE_API == 1
|
||||||
this time and could possible refill the queue - even if we
|
|
||||||
unblocked because space became available. */
|
|
||||||
|
|
||||||
|
signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
|
||||||
|
{
|
||||||
|
signed portBASE_TYPE xEntryTimeSet = pdFALSE;
|
||||||
|
xTimeOutType xTimeOut;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
taskENTER_CRITICAL();
|
taskENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
/* Is there room on the queue now? To be running we must be
|
/* Is there room on the queue now? To be running we must be
|
||||||
|
@ -516,7 +550,6 @@ xTimeOutType xTimeOut;
|
||||||
{
|
{
|
||||||
traceQUEUE_SEND( pxQueue );
|
traceQUEUE_SEND( pxQueue );
|
||||||
prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
|
prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
|
||||||
xReturn = pdPASS;
|
|
||||||
|
|
||||||
/* If there was a task waiting for data to arrive on the
|
/* If there was a task waiting for data to arrive on the
|
||||||
queue then unblock it now. */
|
queue then unblock it now. */
|
||||||
|
@ -529,74 +562,28 @@ xTimeOutType xTimeOut;
|
||||||
taskYIELD();
|
taskYIELD();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
return pdPASS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Setting xReturn to errQUEUE_FULL will force its timeout
|
if( xTicksToWait == ( portTickType ) 0 )
|
||||||
to be re-evaluated. This is necessary in case interrupts
|
{
|
||||||
and higher priority tasks accessed the queue between this
|
taskEXIT_CRITICAL();
|
||||||
task being unblocked and subsequently attempting to write
|
return errQUEUE_FULL;
|
||||||
to the queue. */
|
}
|
||||||
xReturn = errQUEUE_FULL;
|
else if( xEntryTimeSet == pdFALSE )
|
||||||
|
{
|
||||||
|
vTaskSetTimeOutState( &xTimeOut );
|
||||||
|
xEntryTimeSet = pdTRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
taskEXIT_CRITICAL();
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
if( xReturn == errQUEUE_FULL )
|
taskENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
if( xTicksToWait > ( portTickType ) 0 )
|
|
||||||
{
|
|
||||||
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
|
|
||||||
{
|
|
||||||
xReturn = queueERRONEOUS_UNBLOCK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
traceQUEUE_SEND_FAILED( pxQueue );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
traceQUEUE_SEND_FAILED( pxQueue );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while( xReturn == queueERRONEOUS_UNBLOCK );
|
|
||||||
|
|
||||||
return xReturn;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if configUSE_ALTERNATIVE_API == 1
|
|
||||||
|
|
||||||
signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
|
|
||||||
{
|
|
||||||
signed portBASE_TYPE xReturn = pdPASS;
|
|
||||||
xTimeOutType xTimeOut;
|
|
||||||
|
|
||||||
/* The source code that implements the alternative (Alt) API is
|
|
||||||
simpler because it makes more use of critical sections. This is
|
|
||||||
the approach taken by many other RTOSes, but FreeRTOS.org has the
|
|
||||||
preferred fully featured API too. The fully featured API has more
|
|
||||||
complex code that takes longer to execute, but makes less use of
|
|
||||||
critical sections. */
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
/* If xTicksToWait is zero then we are not going to block even
|
|
||||||
if there is no room in the queue to post. */
|
|
||||||
if( xTicksToWait > ( portTickType ) 0 )
|
|
||||||
{
|
|
||||||
portENTER_CRITICAL();
|
|
||||||
{
|
|
||||||
if( xReturn == pdPASS )
|
|
||||||
{
|
|
||||||
/* This is the first time through - capture the time
|
|
||||||
inside the critical section to ensure we attempt to
|
|
||||||
block at least once. */
|
|
||||||
vTaskSetTimeOutState( &xTimeOut );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( prvIsQueueFull( pxQueue ) )
|
if( prvIsQueueFull( pxQueue ) )
|
||||||
{
|
{
|
||||||
/* Need to call xTaskCheckForTimeout again as time could
|
/* Need to call xTaskCheckForTimeout again as time could
|
||||||
|
@ -606,76 +593,17 @@ xTimeOutType xTimeOut;
|
||||||
{
|
{
|
||||||
traceBLOCKING_ON_QUEUE_SEND( pxQueue );
|
traceBLOCKING_ON_QUEUE_SEND( pxQueue );
|
||||||
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );
|
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );
|
||||||
|
|
||||||
/* This will exit the critical section, then re-enter when
|
|
||||||
the task next runs. */
|
|
||||||
taskYIELD();
|
taskYIELD();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
portEXIT_CRITICAL();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Higher priority tasks and interrupts can execute during
|
|
||||||
this time and could possible refill the queue - even if we
|
|
||||||
unblocked because space became available. */
|
|
||||||
|
|
||||||
taskENTER_CRITICAL();
|
|
||||||
{
|
|
||||||
/* Is there room on the queue now? To be running we must be
|
|
||||||
the highest priority task wanting to access the queue. */
|
|
||||||
if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
|
|
||||||
{
|
|
||||||
traceQUEUE_SEND( pxQueue );
|
|
||||||
prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
|
|
||||||
xReturn = pdPASS;
|
|
||||||
|
|
||||||
/* If there was a task waiting for data to arrive on the
|
|
||||||
queue then unblock it now. */
|
|
||||||
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
|
|
||||||
{
|
|
||||||
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )
|
|
||||||
{
|
|
||||||
/* The unblocked task has a priority higher than
|
|
||||||
our own so yield immediately. */
|
|
||||||
taskYIELD();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Setting xReturn to errQUEUE_FULL will force its timeout
|
taskEXIT_CRITICAL();
|
||||||
to be re-evaluated. This is necessary in case interrupts
|
return errQUEUE_FULL;
|
||||||
and higher priority tasks accessed the queue between this
|
}
|
||||||
task being unblocked and subsequently attempting to write
|
|
||||||
to the queue. */
|
|
||||||
xReturn = errQUEUE_FULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
taskEXIT_CRITICAL();
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
if( xReturn == errQUEUE_FULL )
|
|
||||||
{
|
|
||||||
if( xTicksToWait > ( portTickType ) 0 )
|
|
||||||
{
|
|
||||||
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
|
|
||||||
{
|
|
||||||
xReturn = queueERRONEOUS_UNBLOCK;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
traceQUEUE_SEND_FAILED( pxQueue );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
traceQUEUE_SEND_FAILED( pxQueue );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while( xReturn == queueERRONEOUS_UNBLOCK );
|
|
||||||
|
|
||||||
return xReturn;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configUSE_ALTERNATIVE_API */
|
#endif /* configUSE_ALTERNATIVE_API */
|
||||||
|
@ -685,58 +613,12 @@ xTimeOutType xTimeOut;
|
||||||
|
|
||||||
signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )
|
signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )
|
||||||
{
|
{
|
||||||
signed portBASE_TYPE xReturn = pdTRUE;
|
signed portBASE_TYPE xEntryTimeSet = pdFALSE;
|
||||||
xTimeOutType xTimeOut;
|
xTimeOutType xTimeOut;
|
||||||
signed portCHAR *pcOriginalReadPosition;
|
signed portCHAR *pcOriginalReadPosition;
|
||||||
|
|
||||||
/* The source code that implements the alternative (Alt) API is
|
for( ;; )
|
||||||
simpler because it makes more use of critical sections. This is
|
|
||||||
the approach taken by many other RTOSes, but FreeRTOS.org has the
|
|
||||||
preferred fully featured API too. The fully featured API has more
|
|
||||||
complex code that takes longer to execute, but makes less use of
|
|
||||||
critical sections. */
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
/* If there are no messages in the queue we may have to block. */
|
|
||||||
if( xTicksToWait > ( portTickType ) 0 )
|
|
||||||
{
|
|
||||||
portENTER_CRITICAL();
|
|
||||||
{
|
|
||||||
if( xReturn == pdPASS )
|
|
||||||
{
|
|
||||||
/* This is the first time through - capture the time
|
|
||||||
inside the critical section to ensure we attempt to
|
|
||||||
block at least once. */
|
|
||||||
vTaskSetTimeOutState( &xTimeOut );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( prvIsQueueEmpty( pxQueue ) )
|
|
||||||
{
|
|
||||||
/* Need to call xTaskCheckForTimeout again as time could
|
|
||||||
have passed since it was last called if this is not the
|
|
||||||
first time around this loop. */
|
|
||||||
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
|
|
||||||
{
|
|
||||||
traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );
|
|
||||||
|
|
||||||
#if ( configUSE_MUTEXES == 1 )
|
|
||||||
{
|
|
||||||
if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
|
|
||||||
{
|
|
||||||
vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );
|
|
||||||
taskYIELD();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
portEXIT_CRITICAL();
|
|
||||||
}
|
|
||||||
|
|
||||||
taskENTER_CRITICAL();
|
taskENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
|
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
|
||||||
|
@ -788,43 +670,66 @@ xTimeOutType xTimeOut;
|
||||||
the pending ready list as the scheduler is still suspended. */
|
the pending ready list as the scheduler is still suspended. */
|
||||||
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
|
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
|
||||||
{
|
{
|
||||||
/* The task waiting has a higher priority that this task. */
|
/* The task waiting has a higher priority than this task. */
|
||||||
taskYIELD();
|
taskYIELD();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xReturn = pdPASS;
|
taskEXIT_CRITICAL();
|
||||||
|
return pdPASS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
xReturn = errQUEUE_EMPTY;
|
if( xTicksToWait == ( portTickType ) 0 )
|
||||||
|
{
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
return errQUEUE_EMPTY;
|
||||||
|
}
|
||||||
|
else if( xEntryTimeSet == pdFALSE )
|
||||||
|
{
|
||||||
|
vTaskSetTimeOutState( &xTimeOut );
|
||||||
|
xEntryTimeSet = pdTRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
taskEXIT_CRITICAL();
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
if( xReturn == errQUEUE_EMPTY )
|
taskENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
if( xTicksToWait > ( portTickType ) 0 )
|
if( prvIsQueueEmpty( pxQueue ) )
|
||||||
{
|
{
|
||||||
|
/* Need to call xTaskCheckForTimeout again as time could
|
||||||
|
have passed since it was last called if this is not the
|
||||||
|
first time around this loop. */
|
||||||
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
|
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
|
||||||
{
|
{
|
||||||
xReturn = queueERRONEOUS_UNBLOCK;
|
traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
traceQUEUE_RECEIVE_FAILED( pxQueue );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
traceQUEUE_RECEIVE_FAILED( pxQueue );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while( xReturn == queueERRONEOUS_UNBLOCK );
|
|
||||||
|
|
||||||
return xReturn;
|
#if ( configUSE_MUTEXES == 1 )
|
||||||
|
{
|
||||||
|
if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
|
||||||
|
{
|
||||||
|
portENTER_CRITICAL();
|
||||||
|
vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );
|
||||||
|
portEXIT_CRITICAL();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );
|
||||||
|
taskYIELD();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
return errQUEUE_EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -886,66 +791,12 @@ unsigned portBASE_TYPE uxSavedInterruptStatus;
|
||||||
|
|
||||||
signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )
|
signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )
|
||||||
{
|
{
|
||||||
signed portBASE_TYPE xReturn = pdTRUE;
|
signed portBASE_TYPE xEntryTimeSet = pdFALSE;
|
||||||
xTimeOutType xTimeOut;
|
xTimeOutType xTimeOut;
|
||||||
signed portCHAR *pcOriginalReadPosition;
|
signed portCHAR *pcOriginalReadPosition;
|
||||||
|
|
||||||
do
|
for( ;; )
|
||||||
{
|
{
|
||||||
/* If there are no messages in the queue we may have to block. */
|
|
||||||
if( xTicksToWait > ( portTickType ) 0 )
|
|
||||||
{
|
|
||||||
vTaskSuspendAll();
|
|
||||||
prvLockQueue( pxQueue );
|
|
||||||
|
|
||||||
if( xReturn == pdTRUE )
|
|
||||||
{
|
|
||||||
/* This is the first time through - we need to capture the
|
|
||||||
time while the scheduler is locked to ensure we attempt to
|
|
||||||
block at least once. */
|
|
||||||
vTaskSetTimeOutState( &xTimeOut );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( prvIsQueueEmpty( pxQueue ) )
|
|
||||||
{
|
|
||||||
/* Need to call xTaskCheckForTimeout again as time could
|
|
||||||
have passed since it was last called if this is not the
|
|
||||||
first time around this loop. */
|
|
||||||
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
|
|
||||||
{
|
|
||||||
traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );
|
|
||||||
|
|
||||||
#if ( configUSE_MUTEXES == 1 )
|
|
||||||
{
|
|
||||||
if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
|
|
||||||
{
|
|
||||||
portENTER_CRITICAL();
|
|
||||||
vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );
|
|
||||||
portEXIT_CRITICAL();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );
|
|
||||||
prvUnlockQueue( pxQueue );
|
|
||||||
if( !xTaskResumeAll() )
|
|
||||||
{
|
|
||||||
taskYIELD();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
prvUnlockQueue( pxQueue );
|
|
||||||
( void ) xTaskResumeAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
prvUnlockQueue( pxQueue );
|
|
||||||
( void ) xTaskResumeAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
taskENTER_CRITICAL();
|
taskENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
|
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
|
||||||
|
@ -1004,37 +855,68 @@ signed portCHAR *pcOriginalReadPosition;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xReturn = pdPASS;
|
taskEXIT_CRITICAL();
|
||||||
|
return pdPASS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
xReturn = errQUEUE_EMPTY;
|
if( xTicksToWait == ( portTickType ) 0 )
|
||||||
|
{
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
return errQUEUE_EMPTY;
|
||||||
|
}
|
||||||
|
else if( xEntryTimeSet == pdFALSE )
|
||||||
|
{
|
||||||
|
vTaskSetTimeOutState( &xTimeOut );
|
||||||
|
xEntryTimeSet = pdTRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
taskEXIT_CRITICAL();
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
if( xReturn == errQUEUE_EMPTY )
|
vTaskSuspendAll();
|
||||||
{
|
prvLockQueue( pxQueue );
|
||||||
if( xTicksToWait > ( portTickType ) 0 )
|
|
||||||
|
if( prvIsQueueEmpty( pxQueue ) )
|
||||||
{
|
{
|
||||||
|
/* Need to call xTaskCheckForTimeout again as time could
|
||||||
|
have passed since it was last called if this is not the
|
||||||
|
first time around this loop. */
|
||||||
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
|
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
|
||||||
{
|
{
|
||||||
xReturn = queueERRONEOUS_UNBLOCK;
|
traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );
|
||||||
}
|
|
||||||
else
|
#if ( configUSE_MUTEXES == 1 )
|
||||||
{
|
{
|
||||||
traceQUEUE_RECEIVE_FAILED( pxQueue );
|
if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
|
||||||
|
{
|
||||||
|
portENTER_CRITICAL();
|
||||||
|
vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );
|
||||||
|
portEXIT_CRITICAL();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );
|
||||||
|
prvUnlockQueue( pxQueue );
|
||||||
|
if( !xTaskResumeAll() )
|
||||||
|
{
|
||||||
|
taskYIELD();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
traceQUEUE_RECEIVE_FAILED( pxQueue );
|
prvUnlockQueue( pxQueue );
|
||||||
|
( void ) xTaskResumeAll();
|
||||||
|
return errQUEUE_EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prvUnlockQueue( pxQueue );
|
||||||
|
( void ) xTaskResumeAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} while( xReturn == queueERRONEOUS_UNBLOCK );
|
|
||||||
|
|
||||||
return xReturn;
|
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue