Skip to content

Commit

Permalink
fix(freertos-smp): Added check for empty pxEventList in xTaskRemoveFr…
Browse files Browse the repository at this point in the history
…omEventList()

In SMP, a task running on the other core or an ISR can remove a task
from the event list. There could be situation wherein a task contesting
for the kernel lock may try to remove a task from the event list which
has been emptied out by another task or ISR.
  • Loading branch information
sudeep-mohanty committed Jul 17, 2024
1 parent b54f3c4 commit fa413a3
Showing 1 changed file with 20 additions and 5 deletions.
25 changes: 20 additions & 5 deletions tasks.c
Original file line number Diff line number Diff line change
Expand Up @@ -5482,7 +5482,12 @@ BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList )

traceENTER_xTaskRemoveFromEventList( pxEventList );

#if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) )
#if ( ! ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) )

/* THIS FUNCTION MUST BE CALLED FROM A CRITICAL SECTION. It can also be
* called from a critical section within an ISR. */

#else /* #if ( ! ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) ) */
/* Lock the kernel data group as we are about to access its members */
UBaseType_t uxSavedInterruptStatus;

Expand All @@ -5495,11 +5500,13 @@ BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList )
uxSavedInterruptStatus = 0;
taskLOCK_DATA_GROUP( &xTaskSpinlock, &xISRSpinlock );
}
#else /* #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) */

/* THIS FUNCTION MUST BE CALLED FROM A CRITICAL SECTION. It can also be
* called from a critical section within an ISR. */
#endif /* #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) */
/* Before taking the kernel lock, another task/ISR could have already
* emptied the pxEventList. So we insert a check here to see if
* pxEventList is empty before attempting to remove an item from it. */
if( listLIST_IS_EMPTY( pxEventList ) == pdFALSE )
{
#endif /* #if ( ! ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) ) */

/* The event list is sorted in priority order, so the first in the list can
* be removed as it is known to be the highest priority. Remove the TCB from
Expand Down Expand Up @@ -5580,6 +5587,14 @@ BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList )
#endif /* #if ( configNUMBER_OF_CORES == 1 ) */

#if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) )
}
else
{
/* The pxEventList was emptied before we entered the critical
* section, Nothing to do except return pdFALSE. */
xReturn = pdFALSE;
}

/* We are done accessing the kernel data group. Unlock it. */
if( portCHECK_IF_IN_ISR() == pdTRUE )
{
Expand Down

0 comments on commit fa413a3

Please sign in to comment.