mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-09 20:41:14 +00:00
freertos(IDF): Use common macros for SMP specific critical sections
In IDF FreeRTOS, when building for SMP, there are numerous functions which require different critical sections when compared to single-core. This commit encapsulates those difference into a common set of macros whose behavior depends on "configNUM_CORES > 1". As such... - Vanilla behavior has been restored for some functions when building for single core (i.e., used to call taskENTER_CRITICAL, now disables interrupts mactching vanilla behavior). - Reduces number of "#ifdef (configNUM_CORES > 1)" in functions - Any SMP only critical sections are now wrapped by "#ifdef (configNUM_CORES > 1)" and properly documented via comments.
This commit is contained in:
@@ -80,9 +80,7 @@ typedef struct EventGroupDef_t
|
||||
uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */
|
||||
#endif
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
portMUX_TYPE xEventGroupLock; /* Spinlock required for SMP critical sections */
|
||||
#endif // ESP_PLATFORM
|
||||
portMUX_TYPE xEventGroupLock; /* Spinlock required for SMP critical sections */
|
||||
} EventGroup_t;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -225,11 +223,7 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ESP_PLATFORM /* IDF-3755 */
|
||||
taskENTER_CRITICAL( &( pxEventBits->xEventGroupLock ) );
|
||||
#else
|
||||
vTaskSuspendAll();
|
||||
#endif // ESP_PLATFORM
|
||||
prvENTER_CRITICAL_OR_SUSPEND_ALL( &( pxEventBits->xEventGroupLock ) );
|
||||
{
|
||||
uxOriginalBitValue = pxEventBits->uxEventBits;
|
||||
|
||||
@@ -272,12 +266,7 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef ESP_PLATFORM /* IDF-3755 */
|
||||
taskEXIT_CRITICAL( &( pxEventBits->xEventGroupLock ) );
|
||||
xAlreadyYielded = pdFALSE;
|
||||
#else
|
||||
xAlreadyYielded = xTaskResumeAll();
|
||||
#endif // ESP_PLATFORM
|
||||
xAlreadyYielded = prvEXIT_CRITICAL_OR_RESUME_ALL( &( pxEventBits->xEventGroupLock ) );
|
||||
|
||||
if( xTicksToWait != ( TickType_t ) 0 )
|
||||
{
|
||||
@@ -361,11 +350,7 @@ EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ESP_PLATFORM /* IDF-3755 */
|
||||
taskENTER_CRITICAL( &( pxEventBits->xEventGroupLock ) );
|
||||
#else
|
||||
vTaskSuspendAll();
|
||||
#endif // ESP_PLATFORM
|
||||
prvENTER_CRITICAL_OR_SUSPEND_ALL( &( pxEventBits->xEventGroupLock ) );
|
||||
{
|
||||
const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits;
|
||||
|
||||
@@ -433,12 +418,7 @@ EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
|
||||
traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor );
|
||||
}
|
||||
}
|
||||
#ifdef ESP_PLATFORM /* IDF-3755 */
|
||||
taskEXIT_CRITICAL( &( pxEventBits->xEventGroupLock ) );
|
||||
xAlreadyYielded = pdFALSE;
|
||||
#else
|
||||
xAlreadyYielded = xTaskResumeAll();
|
||||
#endif // ESP_PLATFORM
|
||||
xAlreadyYielded = prvEXIT_CRITICAL_OR_RESUME_ALL( &( pxEventBits->xEventGroupLock ) );
|
||||
|
||||
if( xTicksToWait != ( TickType_t ) 0 )
|
||||
{
|
||||
@@ -581,15 +561,14 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
|
||||
|
||||
pxList = &( pxEventBits->xTasksWaitingForBits );
|
||||
pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||
#ifdef ESP_PLATFORM /* IDF-3755 */
|
||||
taskENTER_CRITICAL( &( pxEventBits->xEventGroupLock ) );
|
||||
|
||||
prvENTER_CRITICAL_OR_SUSPEND_ALL( &( pxEventBits->xEventGroupLock ) );
|
||||
#if ( configNUM_CORES > 1 )
|
||||
|
||||
/* We are about to traverse a task list which is a kernel data structure.
|
||||
* Thus we need to call vTaskTakeKernelLock() to take the kernel lock. */
|
||||
vTaskTakeKernelLock();
|
||||
#else
|
||||
vTaskSuspendAll();
|
||||
#endif // ESP_PLATFORM
|
||||
#endif /* configNUM_CORES > 1 */
|
||||
{
|
||||
traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet );
|
||||
|
||||
@@ -661,13 +640,11 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
|
||||
* bit was set in the control word. */
|
||||
pxEventBits->uxEventBits &= ~uxBitsToClear;
|
||||
}
|
||||
#ifdef ESP_PLATFORM /* IDF-3755 */
|
||||
/* Release the previously taken kernel lock, then release the event group spinlock. */
|
||||
#if ( configNUM_CORES > 1 )
|
||||
/* Release the previously taken kernel lock. */
|
||||
vTaskReleaseKernelLock();
|
||||
taskEXIT_CRITICAL( &( pxEventBits->xEventGroupLock ) );
|
||||
#else
|
||||
( void ) xTaskResumeAll();
|
||||
#endif // ESP_PLATFORM
|
||||
#endif /* configNUM_CORES > 1 */
|
||||
( void ) prvEXIT_CRITICAL_OR_RESUME_ALL( &( pxEventBits->xEventGroupLock ) );
|
||||
|
||||
return pxEventBits->uxEventBits;
|
||||
}
|
||||
@@ -678,18 +655,16 @@ void vEventGroupDelete( EventGroupHandle_t xEventGroup )
|
||||
EventGroup_t * pxEventBits = xEventGroup;
|
||||
const List_t * pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
|
||||
|
||||
prvENTER_CRITICAL_OR_SUSPEND_ALL( &( pxEventBits->xEventGroupLock ) );
|
||||
#if ( configNUM_CORES > 1 )
|
||||
|
||||
/* We are about to traverse a task list which is a kernel data structure.
|
||||
* Thus we need to call vTaskTakeKernelLock() to take the kernel lock. */
|
||||
vTaskTakeKernelLock();
|
||||
#endif /* configNUM_CORES > 1 */
|
||||
{
|
||||
traceEVENT_GROUP_DELETE( xEventGroup );
|
||||
|
||||
/* IDF-3755 */
|
||||
taskENTER_CRITICAL( &( pxEventBits->xEventGroupLock ) );
|
||||
#ifdef ESP_PLATFORM
|
||||
|
||||
/* We are about to traverse a task list which is a kernel data structure.
|
||||
* Thus we need to call vTaskTakeKernelLock() to take the kernel lock. */
|
||||
vTaskTakeKernelLock();
|
||||
#endif
|
||||
|
||||
while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 )
|
||||
{
|
||||
/* Unblock the task, returning 0 as the event list is being deleted
|
||||
@@ -697,34 +672,33 @@ void vEventGroupDelete( EventGroupHandle_t xEventGroup )
|
||||
configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) );
|
||||
vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET );
|
||||
}
|
||||
}
|
||||
#if ( configNUM_CORES > 1 )
|
||||
/* Release the previously taken kernel lock. */
|
||||
vTaskReleaseKernelLock();
|
||||
#endif /* configNUM_CORES > 1 */
|
||||
prvEXIT_CRITICAL_OR_RESUME_ALL( &( pxEventBits->xEventGroupLock ) );
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
/* Release the previously taken kernel lock. */
|
||||
vTaskReleaseKernelLock();
|
||||
#endif
|
||||
taskEXIT_CRITICAL( &( pxEventBits->xEventGroupLock ) );
|
||||
|
||||
#if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )
|
||||
#if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )
|
||||
{
|
||||
/* The event group can only have been allocated dynamically - free
|
||||
* it again. */
|
||||
vPortFree( pxEventBits );
|
||||
}
|
||||
#elif ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
||||
{
|
||||
/* The event group could have been allocated statically or
|
||||
* dynamically, so check before attempting to free the memory. */
|
||||
if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE )
|
||||
{
|
||||
/* The event group can only have been allocated dynamically - free
|
||||
* it again. */
|
||||
vPortFree( pxEventBits );
|
||||
}
|
||||
#elif ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
||||
else
|
||||
{
|
||||
/* The event group could have been allocated statically or
|
||||
* dynamically, so check before attempting to free the memory. */
|
||||
if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE )
|
||||
{
|
||||
vPortFree( pxEventBits );
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
}
|
||||
}
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
Reference in New Issue
Block a user