freertos: Fix event group task list race condition

FreeRTOS synchronization primitives (e.g., queues, eventgroups) use various event lists (i.e., task lists) to track what
tasks are blocked on a current primitive. Usually these event lists are accessed via one of the event lists functions
(such as vTask[PlaceOn|RemoveFrom]UnorderedEventList()), which in turn ensure that the global task list spinlock
(xTaskQueueMutex) is taken when accessing these lists.

However, some functions in event_groups.c manually traverse their event lists. Thus if a tick interrupt occurs on
another core during traversal and that tick interrupt unblocks a task on the event list being traversed, the event list
will be corrupted.

This commit modifies the following event_groups.c functions so that they take the global task list lock before
traversing their event list.

- xEventGroupSetBits()
- vEventGroupDelete()
This commit is contained in:
Darian Leung
2022-07-19 12:02:19 +08:00
committed by BOT
parent cd9541fdb4
commit ad39eaaeb0
3 changed files with 41 additions and 0 deletions

View File

@@ -3563,6 +3563,18 @@ UBaseType_t i, uxTargetCPU;
}
/*-----------------------------------------------------------*/
void vTaskTakeEventListLock( void )
{
/* We call the tasks.c critical section macro to take xTaskQueueMutex */
taskENTER_CRITICAL(&xTaskQueueMutex);
}
void vTaskReleaseEventListLock( void )
{
/* We call the tasks.c critical section macro to release xTaskQueueMutex */
taskEXIT_CRITICAL(&xTaskQueueMutex);
}
BaseType_t xTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue )
{
TCB_t *pxUnblockedTCB;