Merge branch 'bugfix/freertos_fix_unordered_event_list' into 'master'

freertos: Updated vTaskRemoveFromUnorderedEventList() to consider scheduler state before adding task to ready list

Closes IDF-5785

See merge request espressif/esp-idf!23482
This commit is contained in:
Zim Kalinowski
2023-05-10 01:48:47 +08:00

View File

@@ -4064,6 +4064,15 @@ void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem,
configASSERT( pxUnblockedTCB ); configASSERT( pxUnblockedTCB );
( void ) uxListRemove( pxEventListItem ); ( void ) uxListRemove( pxEventListItem );
/* Add the task to the ready list if a core with compatible affinity
* has NOT suspended its scheduler. This occurs when:
* - The task is pinned, and the pinned core's scheduler is running
* - The task is unpinned, and at least one of the core's scheduler is running */
if( taskCAN_BE_SCHEDULED( pxUnblockedTCB ) )
{
( void ) uxListRemove( &( pxUnblockedTCB->xStateListItem ) );
prvAddTaskToReadyList( pxUnblockedTCB );
#if ( configUSE_TICKLESS_IDLE != 0 ) #if ( configUSE_TICKLESS_IDLE != 0 )
{ {
/* If a task is blocked on a kernel object then xNextTaskUnblockTime /* If a task is blocked on a kernel object then xNextTaskUnblockTime
@@ -4077,12 +4086,27 @@ void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem,
prvResetNextTaskUnblockTime(); prvResetNextTaskUnblockTime();
} }
#endif #endif
}
else
{
/* We arrive here due to one of the following possibilities:
* - The task is pinned to core X and core X has suspended its scheduler
* - The task is unpinned and both cores have suspend their schedulers
* Therefore, we add the task to one of the pending lists:
* - If the task is pinned to core X, add it to core X's pending list
* - If the task is unpinned, add it to the current core's pending list */
BaseType_t xPendingListCore;
#if ( configNUM_CORES > 1 )
xPendingListCore = ( ( pxUnblockedTCB->xCoreID == tskNO_AFFINITY ) ? xCurCoreID : pxUnblockedTCB->xCoreID );
#else
xPendingListCore = 0;
#endif /* configNUM_CORES > 1 */
configASSERT( uxSchedulerSuspended[ xPendingListCore ] != ( UBaseType_t ) 0U );
/* Remove the task from the delayed list and add it to the ready list. The /* The delayed and ready lists cannot be accessed, so hold this task
* scheduler is suspended so interrupts will not be accessing the ready * pending until the scheduler is resumed. */
* lists. */ vListInsertEnd( &( xPendingReadyList[ xPendingListCore ] ), &( pxUnblockedTCB->xEventListItem ) );
( void ) uxListRemove( &( pxUnblockedTCB->xStateListItem ) ); }
prvAddTaskToReadyList( pxUnblockedTCB );
if( prvCheckForYield( pxUnblockedTCB, xCurCoreID, pdFALSE ) ) if( prvCheckForYield( pxUnblockedTCB, xCurCoreID, pdFALSE ) )
{ {