Skip to content

Commit 0dc29ca

Browse files
committed
fix(freertos/idf): Add missing critical sections to vTaskSuspendAll()
vTaskSuspendAll() requires critical sections when building for SMP. Otherwise, it is possible for a task to switch cores in between getting the core ID and before incremented uxSchedulerSuspended.
1 parent ea010f8 commit 0dc29ca

File tree

1 file changed

+18
-11
lines changed
  • components/freertos/FreeRTOS-Kernel

1 file changed

+18
-11
lines changed

components/freertos/FreeRTOS-Kernel/tasks.c

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2462,22 +2462,29 @@ void vTaskEndScheduler( void )
24622462

24632463
void vTaskSuspendAll( void )
24642464
{
2465-
/* A critical section is not required as the variable is of type
2465+
/* For SMP, we need to take the kernel lock here as we are about to access
2466+
* kernel data structures.
2467+
*
2468+
* For single-core, a critical section is not required as the variable is of type
24662469
* BaseType_t. Please read Richard Barry's reply in the following link to a
24672470
* post in the FreeRTOS support forum before reporting this as a bug! -
24682471
* https://goo.gl/wu4acr */
2472+
prvENTER_CRITICAL_SMP_ONLY( &xKernelLock );
2473+
{
2474+
/* portSOFTWARE_BARRIER() is only implemented for emulated/simulated ports that
2475+
* do not otherwise exhibit real time behaviour. */
2476+
portSOFTWARE_BARRIER();
24692477

2470-
/* portSOFTWARE_BARRIER() is only implemented for emulated/simulated ports that
2471-
* do not otherwise exhibit real time behaviour. */
2472-
portSOFTWARE_BARRIER();
2473-
2474-
/* The scheduler is suspended if uxSchedulerSuspended is non-zero. An increment
2475-
* is used to allow calls to vTaskSuspendAll() to nest. */
2476-
++uxSchedulerSuspended[ portGET_CORE_ID() ];
2478+
/* The scheduler is suspended if uxSchedulerSuspended is non-zero. An increment
2479+
* is used to allow calls to vTaskSuspendAll() to nest. */
2480+
++uxSchedulerSuspended[ portGET_CORE_ID() ];
24772481

2478-
/* Enforces ordering for ports and optimised compilers that may otherwise place
2479-
* the above increment elsewhere. */
2480-
portMEMORY_BARRIER();
2482+
/* Enforces ordering for ports and optimised compilers that may otherwise place
2483+
* the above increment elsewhere. */
2484+
portMEMORY_BARRIER();
2485+
}
2486+
/* Release the previously taken kernel lock. */
2487+
prvEXIT_CRITICAL_SMP_ONLY( &xKernelLock );
24812488
}
24822489
/*----------------------------------------------------------*/
24832490

0 commit comments

Comments
 (0)