]> granicus.if.org Git - esp-idf/commitdiff
freertos: fix protection issue in freertos queue event list
authorLiu Zhi Fu <liuzhifu@espressif.com>
Tue, 24 Jan 2017 12:40:14 +0000 (20:40 +0800)
committerLiu Zhi Fu <liuzhifu@espressif.com>
Fri, 10 Feb 2017 02:30:17 +0000 (10:30 +0800)
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 commit is to fix this bug.

may cause

components/freertos/tasks.c

index f885e9c013cfc3479b617545348a87431ef65c0a..02d184287480a81ee93fecd3f71a03d5a35e74eb 100644 (file)
@@ -3012,9 +3012,14 @@ BaseType_t xReturn;
 
        This function assumes that a check has already been made to ensure that
        pxEventList is not empty. */
-       pxUnblockedTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
-       configASSERT( pxUnblockedTCB );
-       ( void ) uxListRemove( &( pxUnblockedTCB->xEventListItem ) );
+       if ( ( listLIST_IS_EMPTY( pxEventList ) ) == pdFALSE ) {
+               pxUnblockedTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
+               configASSERT( pxUnblockedTCB );
+               ( void ) uxListRemove( &( pxUnblockedTCB->xEventListItem ) );
+       } else {
+               taskEXIT_CRITICAL_ISR(&xTaskQueueMutex);
+               return 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
                pending until the scheduler is resumed. */
-               taskENTER_CRITICAL(&xTaskQueueMutex);
                vListInsertEnd( &( xPendingReadyList[ xPortGetCoreID() ] ), &( pxUnblockedTCB->xEventListItem ) );
-               taskEXIT_CRITICAL(&xTaskQueueMutex);
        }
 
        if ( tskCAN_RUN_HERE(pxUnblockedTCB->xCoreID) && pxUnblockedTCB->uxPriority >= pxCurrentTCB[ xPortGetCoreID() ]->uxPriority )