@@ -3819,7 +3819,30 @@ void vTaskSuspendAll( void )
3819
3819
#if ( configNUMBER_OF_CORES == 1 )
3820
3820
{
3821
3821
/* A critical section is not required as the variable is of type
3822
- * BaseType_t. */
3822
+ * BaseType_t. Each task maintains its own context, and a context switch
3823
+ * cannot occur if the variable is non zero. So, as long as the writing
3824
+ * from the register back into the memory is atomic, it is not a
3825
+ * problem.
3826
+ *
3827
+ * Consider the following scenario, which starts with
3828
+ * uxSchedulerSuspended at zero.
3829
+ *
3830
+ * 1. load uxSchedulerSuspended into register.
3831
+ * 2. Now a context switch causes another task to run, and the other
3832
+ * task uses the same variable. The other task will see the variable
3833
+ * as zero because the variable has not yet been updated by the
3834
+ * original task. Eventually the original task runs again. **That can
3835
+ * only happen when uxSchedulerSuspended is once again zero**. When
3836
+ * the original task runs again, the contents of the CPU registers
3837
+ * are restored to exactly how they were when it was switched out -
3838
+ * therefore the value it read into the register still matches the
3839
+ * value of the uxSchedulerSuspended variable.
3840
+ *
3841
+ * 3. increment register.
3842
+ * 4. store register into uxSchedulerSuspended. The value restored to
3843
+ * uxSchedulerSuspended will be the correct value of 1, even though
3844
+ * the variable was used by other tasks in the mean time.
3845
+ */
3823
3846
3824
3847
/* portSOFTWARE_BARRIER() is only implemented for emulated/simulated ports that
3825
3848
* do not otherwise exhibit real time behaviour. */
0 commit comments