mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-04 21:24:32 +02:00
freertos: Updated vTaskRemoveFromUnorderedEventList() to consider scheduler state before adding task to ready list
vTaskRemoveFromUnorderedEventList() runs under the assumption that the scheduler is suspended during the call. However, for IDF FreeRTOS, this is not true. When dual-core system is active, this API call is made in a critical section but without suspending the scheduler. This commit updates the vTaskRemoveFromUnorderedEventList() function to now consider the scheduler state on either cores before adding a task to the ready list.
This commit is contained in:
@@ -4064,6 +4064,15 @@ void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem,
|
||||
configASSERT( pxUnblockedTCB );
|
||||
( 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 a task is blocked on a kernel object then xNextTaskUnblockTime
|
||||
@@ -4077,12 +4086,27 @@ void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem,
|
||||
prvResetNextTaskUnblockTime();
|
||||
}
|
||||
#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
|
||||
* scheduler is suspended so interrupts will not be accessing the ready
|
||||
* lists. */
|
||||
( void ) uxListRemove( &( pxUnblockedTCB->xStateListItem ) );
|
||||
prvAddTaskToReadyList( pxUnblockedTCB );
|
||||
/* The delayed and ready lists cannot be accessed, so hold this task
|
||||
* pending until the scheduler is resumed. */
|
||||
vListInsertEnd( &( xPendingReadyList[ xPendingListCore ] ), &( pxUnblockedTCB->xEventListItem ) );
|
||||
}
|
||||
|
||||
if( prvCheckForYield( pxUnblockedTCB, xCurCoreID, pdFALSE ) )
|
||||
{
|
||||
|
Reference in New Issue
Block a user