Skip to content

Commit fa413a3

Browse files
fix(freertos-smp): Added check for empty pxEventList in xTaskRemoveFromEventList()
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.
1 parent b54f3c4 commit fa413a3

File tree

1 file changed

+20
-5
lines changed

1 file changed

+20
-5
lines changed

tasks.c

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5482,7 +5482,12 @@ BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList )
54825482

54835483
traceENTER_xTaskRemoveFromEventList( pxEventList );
54845484

5485-
#if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) )
5485+
#if ( ! ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) )
5486+
5487+
/* THIS FUNCTION MUST BE CALLED FROM A CRITICAL SECTION. It can also be
5488+
* called from a critical section within an ISR. */
5489+
5490+
#else /* #if ( ! ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) ) */
54865491
/* Lock the kernel data group as we are about to access its members */
54875492
UBaseType_t uxSavedInterruptStatus;
54885493

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

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

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

55825589
#if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) )
5590+
}
5591+
else
5592+
{
5593+
/* The pxEventList was emptied before we entered the critical
5594+
* section, Nothing to do except return pdFALSE. */
5595+
xReturn = pdFALSE;
5596+
}
5597+
55835598
/* We are done accessing the kernel data group. Unlock it. */
55845599
if( portCHECK_IF_IN_ISR() == pdTRUE )
55855600
{

0 commit comments

Comments
 (0)