diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c index 955587ba42..0baffbcd82 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c @@ -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); diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c index 4cd6918472..d39faf60f0 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c @@ -145,9 +145,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]); diff --git a/components/freertos/FreeRTOS-Kernel/portable/linux/port.c b/components/freertos/FreeRTOS-Kernel/portable/linux/port.c index 33253f2240..4e851768c7 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/linux/port.c +++ b/components/freertos/FreeRTOS-Kernel/portable/linux/port.c @@ -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 ) diff --git a/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c b/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c index 29cc3fe096..646fa7686e 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c +++ b/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c @@ -568,9 +568,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]); @@ -623,8 +627,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]); } diff --git a/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c b/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c index 9722a2c308..b35b71ac12 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c +++ b/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c @@ -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]); diff --git a/components/freertos/FreeRTOS-Kernel/tasks.c b/components/freertos/FreeRTOS-Kernel/tasks.c index 2482826674..8d06ea30b0 100644 --- a/components/freertos/FreeRTOS-Kernel/tasks.c +++ b/components/freertos/FreeRTOS-Kernel/tasks.c @@ -3856,7 +3856,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 */