Merge branch 'bugfix/fix_protection_of_queue_list' into 'master'

freertos: fix protection issue in freertos queue event list

When functions in queue.c calls listLIST_IS_EMPTY() to check queue event list, the queue list is
protected by queue mutex, on the other hand, when xTaskIncrementTick() modify the queue list, the
 queue list is protected by xTaskQueueMutex, this may cause xTaskRemoveFromEventList operate on
the empty queue list and cause problem.
This change works around the problem by reducing the window where the race condition can happen.

See merge request !465
This commit is contained in:
Ivan Grokhotkov
2017-02-15 13:25:51 +08:00

View File

@@ -3012,9 +3012,14 @@ BaseType_t xReturn;
This function assumes that a check has already been made to ensure that This function assumes that a check has already been made to ensure that
pxEventList is not empty. */ pxEventList is not empty. */
pxUnblockedTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); if ( ( listLIST_IS_EMPTY( pxEventList ) ) == pdFALSE ) {
configASSERT( pxUnblockedTCB ); pxUnblockedTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
( void ) uxListRemove( &( pxUnblockedTCB->xEventListItem ) ); configASSERT( pxUnblockedTCB );
( void ) uxListRemove( &( pxUnblockedTCB->xEventListItem ) );
} else {
taskEXIT_CRITICAL_ISR(&xTaskQueueMutex);
return pdFALSE;
}
if( uxSchedulerSuspended[ xPortGetCoreID() ] == ( UBaseType_t ) pdFALSE ) if( uxSchedulerSuspended[ xPortGetCoreID() ] == ( UBaseType_t ) pdFALSE )
{ {
@@ -3025,9 +3030,7 @@ BaseType_t xReturn;
{ {
/* The delayed and ready lists cannot be accessed, so hold this task /* The delayed and ready lists cannot be accessed, so hold this task
pending until the scheduler is resumed. */ pending until the scheduler is resumed. */
taskENTER_CRITICAL(&xTaskQueueMutex);
vListInsertEnd( &( xPendingReadyList[ xPortGetCoreID() ] ), &( pxUnblockedTCB->xEventListItem ) ); vListInsertEnd( &( xPendingReadyList[ xPortGetCoreID() ] ), &( pxUnblockedTCB->xEventListItem ) );
taskEXIT_CRITICAL(&xTaskQueueMutex);
} }
if ( tskCAN_RUN_HERE(pxUnblockedTCB->xCoreID) && pxUnblockedTCB->uxPriority >= pxCurrentTCB[ xPortGetCoreID() ]->uxPriority ) if ( tskCAN_RUN_HERE(pxUnblockedTCB->xCoreID) && pxUnblockedTCB->uxPriority >= pxCurrentTCB[ xPortGetCoreID() ]->uxPriority )