signed portBASE_TYPE xEntryTimeSet = pdFALSE;\r
xTimeOutType xTimeOut;\r
\r
signed portBASE_TYPE xEntryTimeSet = pdFALSE;\r
xTimeOutType xTimeOut;\r
\r
+ /* This function relaxes the coding standard somewhat to allow return\r
+ statements within the function itself. This is done in the interest\r
+ of execution time efficiency. */\r
+\r
for( ;; )\r
{\r
taskENTER_CRITICAL();\r
for( ;; )\r
{\r
taskENTER_CRITICAL();\r
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )\r
{\r
/* The unblocked task has a priority higher than\r
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )\r
{\r
/* The unblocked task has a priority higher than\r
- our own so yield immediately. */\r
+ our own so yield immediately. Yes it is ok to do\r
+ this from within the critical section - the kernel\r
+ takes care of that. */\r
{\r
if( xTicksToWait == ( portTickType ) 0 )\r
{\r
{\r
if( xTicksToWait == ( portTickType ) 0 )\r
{\r
+ /* The queue was full and no block time is specified (or \r
+ the block time has expired) so leave now. */\r
taskEXIT_CRITICAL();\r
return errQUEUE_FULL;\r
}\r
else if( xEntryTimeSet == pdFALSE )\r
{\r
taskEXIT_CRITICAL();\r
return errQUEUE_FULL;\r
}\r
else if( xEntryTimeSet == pdFALSE )\r
{\r
+ /* The queue was full and a block time was specified so\r
+ configure the timeout structure. */\r
vTaskSetTimeOutState( &xTimeOut );\r
xEntryTimeSet = pdTRUE;\r
}\r
vTaskSetTimeOutState( &xTimeOut );\r
xEntryTimeSet = pdTRUE;\r
}\r
}\r
taskEXIT_CRITICAL(); \r
\r
}\r
taskEXIT_CRITICAL(); \r
\r
+ /* Interrupts and other tasks can send to and receive from the queue\r
+ now the critical section has been exited. */\r
+\r
vTaskSuspendAll();\r
prvLockQueue( pxQueue );\r
\r
vTaskSuspendAll();\r
prvLockQueue( pxQueue );\r
\r
- if( prvIsQueueFull( pxQueue ) )\r
+ /* Update the timeout state to see if it has expired yet. */\r
+ if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\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( prvIsQueueFull( pxQueue ) )\r
+ { \r
traceBLOCKING_ON_QUEUE_SEND( pxQueue );\r
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );\r
\r
traceBLOCKING_ON_QUEUE_SEND( pxQueue );\r
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );\r
\r
prvUnlockQueue( pxQueue );\r
prvUnlockQueue( pxQueue );\r
- ( void ) xTaskResumeAll();\r
- return errQUEUE_FULL;\r
+ ( void ) xTaskResumeAll(); \r
+ /* The timeout has expired. */\r
prvUnlockQueue( pxQueue );\r
( void ) xTaskResumeAll();\r
prvUnlockQueue( pxQueue );\r
( void ) xTaskResumeAll();\r
+ return errQUEUE_FULL;\r
\r
taskENTER_CRITICAL();\r
{\r
\r
taskENTER_CRITICAL();\r
{\r
- if( prvIsQueueFull( pxQueue ) )\r
+ if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\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( prvIsQueueFull( pxQueue ) )\r
+ { \r
traceBLOCKING_ON_QUEUE_SEND( pxQueue );\r
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );\r
taskYIELD();\r
}\r
traceBLOCKING_ON_QUEUE_SEND( pxQueue );\r
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );\r
taskYIELD();\r
}\r
- else\r
- {\r
- taskEXIT_CRITICAL();\r
- return errQUEUE_FULL;\r
- }\r
+ }\r
+ else\r
+ {\r
+ taskEXIT_CRITICAL();\r
+ return errQUEUE_FULL;\r
}\r
}\r
taskEXIT_CRITICAL();\r
}\r
}\r
taskEXIT_CRITICAL();\r
\r
taskENTER_CRITICAL();\r
{\r
\r
taskENTER_CRITICAL();\r
{\r
- if( prvIsQueueEmpty( pxQueue ) )\r
+ if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\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( prvIsQueueEmpty( pxQueue ) )\r
+ { \r
traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );\r
\r
#if ( configUSE_MUTEXES == 1 )\r
traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );\r
\r
#if ( configUSE_MUTEXES == 1 )\r
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );\r
taskYIELD();\r
}\r
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );\r
taskYIELD();\r
}\r
- else\r
- {\r
- taskEXIT_CRITICAL();\r
- return errQUEUE_EMPTY;\r
- }\r
+ }\r
+ else\r
+ {\r
+ taskEXIT_CRITICAL();\r
+ return errQUEUE_EMPTY;\r
}\r
}\r
taskEXIT_CRITICAL();\r
}\r
}\r
taskEXIT_CRITICAL();\r
xTimeOutType xTimeOut;\r
signed portCHAR *pcOriginalReadPosition;\r
\r
xTimeOutType xTimeOut;\r
signed portCHAR *pcOriginalReadPosition;\r
\r
+ /* This function relaxes the coding standard somewhat to allow return\r
+ statements within the function itself. This is done in the interest\r
+ of execution time efficiency. */\r
+\r
for( ;; )\r
{\r
taskENTER_CRITICAL();\r
{\r
for( ;; )\r
{\r
taskENTER_CRITICAL();\r
{\r
+ /* Is there space on the queue now? To be running we must be\r
+ the highest priority task wanting to access the queue. */ \r
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
{\r
/* Remember our read position in case we are just peeking. */\r
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
{\r
/* Remember our read position in case we are just peeking. */\r
{\r
if( xTicksToWait == ( portTickType ) 0 )\r
{\r
{\r
if( xTicksToWait == ( portTickType ) 0 )\r
{\r
+ /* The queue was empty and no block time is specified (or \r
+ the block time has expired) so leave now. */ \r
taskEXIT_CRITICAL();\r
return errQUEUE_EMPTY;\r
}\r
else if( xEntryTimeSet == pdFALSE )\r
{\r
taskEXIT_CRITICAL();\r
return errQUEUE_EMPTY;\r
}\r
else if( xEntryTimeSet == pdFALSE )\r
{\r
+ /* The queue was empty and a block time was specified so\r
+ configure the timeout structure. */ \r
vTaskSetTimeOutState( &xTimeOut );\r
xEntryTimeSet = pdTRUE;\r
}\r
vTaskSetTimeOutState( &xTimeOut );\r
xEntryTimeSet = pdTRUE;\r
}\r
}\r
taskEXIT_CRITICAL();\r
\r
}\r
taskEXIT_CRITICAL();\r
\r
+ /* Interrupts and other tasks can send to and receive from the queue\r
+ now the critical section has been exited. */\r
+\r
vTaskSuspendAll();\r
prvLockQueue( pxQueue );\r
\r
vTaskSuspendAll();\r
prvLockQueue( pxQueue );\r
\r
- if( prvIsQueueEmpty( pxQueue ) )\r
+ /* Update the timeout state to see if it has expired yet. */\r
+ if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\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
+ if( prvIsQueueEmpty( pxQueue ) )\r
{\r
traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );\r
\r
{\r
traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );\r
\r
if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
{\r
portENTER_CRITICAL();\r
if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
{\r
portENTER_CRITICAL();\r
vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );\r
vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );\r
portEXIT_CRITICAL();\r
}\r
}\r
portEXIT_CRITICAL();\r
}\r
}\r
prvUnlockQueue( pxQueue );\r
( void ) xTaskResumeAll();\r
prvUnlockQueue( pxQueue );\r
( void ) xTaskResumeAll();\r
- return errQUEUE_EMPTY;\r
}\r
}\r
else\r
{\r
prvUnlockQueue( pxQueue );\r
( void ) xTaskResumeAll();\r
}\r
}\r
else\r
{\r
prvUnlockQueue( pxQueue );\r
( void ) xTaskResumeAll();\r
+ return errQUEUE_EMPTY;\r