fix(freertos): Fixed critical section macro in vTaskPlaceOnEventListRestricted()

The vTaskPlaceOnEventListRestricted() did not use the correct macro when
exiting a kernel cirtical section. This does not affect the HW targets
but on the Linux port, this caused an issue as the critical nesting
count became negative, leading to deadlocks. This commit fixes the bug
and updates the linux port to prevent the nesting count from going
negative.
This commit is contained in:
Sudeep Mohanty
2024-08-08 09:24:55 +02:00
parent 876eaf8082
commit 411ef4557a
6 changed files with 31 additions and 2 deletions

View File

@ -90,8 +90,13 @@ void vPortEnterCritical(void)
void vPortExitCritical(void)
{
/* Critical section nesting coung must never be negative */
configASSERT( port_uxCriticalNestingIDF > 0 );
if (port_uxCriticalNestingIDF > 0) {
port_uxCriticalNestingIDF--;
if (port_uxCriticalNestingIDF == 0) {
// Restore the saved interrupt threshold
vPortClearInterruptMask((int)port_uxCriticalOldInterruptStateIDF);

View File

@ -143,9 +143,14 @@ void vPortExitCriticalIDF(portMUX_TYPE *lock)
spinlock_release(lock);
BaseType_t coreID = xPortGetCoreID();
BaseType_t nesting = port_uxCriticalNestingIDF[coreID];
/* Critical section nesting count must never be negative */
configASSERT( nesting > 0 );
if (nesting > 0) {
nesting--;
port_uxCriticalNestingIDF[coreID] = nesting;
//This is the last exit call, restore the saved interrupt level
if ( nesting == 0 ) {
XTOS_RESTORE_JUST_INTLEVEL((int) port_uxCriticalOldInterruptStateIDF[coreID]);

View File

@ -261,7 +261,13 @@ void vPortEnterCritical( void )
void vPortExitCritical( void )
{
uxCriticalNesting--;
if ( uxCriticalNesting > 0 )
{
uxCriticalNesting--;
}
/* Critical section nesting count must always be >= 0. */
configASSERT( uxCriticalNesting >= 0 );
/* If we have reached 0 then re-enable the interrupts. */
if( uxCriticalNesting == 0 )

View File

@ -565,9 +565,13 @@ void __attribute__((optimize("-O3"))) vPortExitCriticalMultiCore(portMUX_TYPE *m
BaseType_t coreID = xPortGetCoreID();
BaseType_t nesting = port_uxCriticalNesting[coreID];
/* Critical section nesting count must never be negative */
configASSERT( nesting > 0 );
if (nesting > 0) {
nesting--;
port_uxCriticalNesting[coreID] = nesting;
//This is the last exit call, restore the saved interrupt level
if ( nesting == 0 ) {
portCLEAR_INTERRUPT_MASK_FROM_ISR(port_uxOldInterruptState[coreID]);
@ -620,8 +624,13 @@ void vPortExitCritical(void)
esp_rom_printf("vPortExitCritical(void) is not supported on single-core targets. Please use vPortExitCriticalMultiCore(portMUX_TYPE *mux) instead.\n");
abort();
#endif /* (configNUM_CORES > 1) */
/* Critical section nesting count must never be negative */
configASSERT( port_uxCriticalNesting[0] > 0 );
if (port_uxCriticalNesting[0] > 0) {
port_uxCriticalNesting[0]--;
if (port_uxCriticalNesting[0] == 0) {
portCLEAR_INTERRUPT_MASK_FROM_ISR(port_uxOldInterruptState[0]);
}

View File

@ -497,9 +497,13 @@ void __attribute__((optimize("-O3"))) vPortExitCritical(portMUX_TYPE *mux)
BaseType_t coreID = xPortGetCoreID();
BaseType_t nesting = port_uxCriticalNesting[coreID];
/* Critical section nesting count must never be negative */
configASSERT( nesting > 0 );
if (nesting > 0) {
nesting--;
port_uxCriticalNesting[coreID] = nesting;
//This is the last exit call, restore the saved interrupt level
if ( nesting == 0 ) {
portCLEAR_INTERRUPT_MASK_FROM_ISR(port_uxOldInterruptState[coreID]);

View File

@ -3819,7 +3819,7 @@ void vTaskPlaceOnUnorderedEventList( List_t * pxEventList,
prvAddCurrentTaskToDelayedList( xTicksToWait, xWaitIndefinitely );
}
/* Release the previously taken kernel lock. */
taskEXIT_CRITICAL( &xKernelLock );
prvEXIT_CRITICAL_SMP_ONLY( &xKernelLock );
}
#endif /* configUSE_TIMERS */