141141 * - If a yield is required on the current core, this macro return pdTRUE
142142 * - if a yield is required on the other core, this macro will internally
143143 * trigger it.
144+ *
145+ * - In SMP, these macros must be called from a critical section (where the
146+ * kernel locks are taken).
147+ * - In single-core, these macros must be called from a critical section or when
148+ * the scheduler is suspended.
144149 */
145150#if ( configNUMBER_OF_CORES > 1 )
146151 #define taskIS_YIELD_REQUIRED ( pxTCB , xYieldEqualPriority ) prvIsYieldRequiredSMP( ( pxTCB ), ( pxTCB )->uxPriority, xYieldEqualPriority )
177182#endif /* configNUMBER_OF_CORES > 1 */
178183/*-----------------------------------------------------------*/
179184
180- /* Macros to check if a particular task is a currently running. */
185+ /* Macros to check if a particular task is a currently running.
186+ *
187+ * - In SMP, these macros must be called from a critical section (where the
188+ * kernel lock is taken).
189+ * - In single-core, these macros must be called from a critical section or when
190+ * the scheduler is suspended */
181191#if ( configNUMBER_OF_CORES > 1 )
182192 #define taskIS_CURRENTLY_RUNNING ( pxTCB ) ( ( ( ( pxTCB ) == pxCurrentTCBs[ 0 ] ) || ( ( pxTCB ) == pxCurrentTCBs[ 1 ] ) ) ? pdTRUE : pdFALSE )
183193 #define taskIS_CURRENTLY_RUNNING_ON_CORE ( pxTCB , xCoreID ) ( ( ( pxTCB ) == pxCurrentTCBs[ ( xCoreID ) ] ) ? pdTRUE : pdFALSE )
193203/*-----------------------------------------------------------*/
194204
195205/* Macro to check if a particular task can currently be scheduled (i.e., is
196- * the scheduler suspended). */
206+ * the scheduler suspended).
207+ *
208+ * - In SMP, these macros must be called from a critical section (where the
209+ * kernel lock is taken).
210+ * - In single-core, these macros must be called from a critical section or when
211+ * the scheduler is suspended */
197212#if ( configNUMBER_OF_CORES > 1 )
198213 #define taskCAN_BE_SCHEDULED ( pxTCB ) prvCheckTaskCanBeScheduledSMP( pxTCB )
199214#else
@@ -569,6 +584,9 @@ static BaseType_t prvCreateIdleTasks( void );
569584 * Exit:
570585 * - Returns pdTRUE if the current core requires yielding
571586 * - The other core will be triggered to yield if required
587+ *
588+ * @note This function must be called from a critical section where the kernel
589+ * lock is taken).
572590 */
573591#if ( configNUMBER_OF_CORES > 1 )
574592
@@ -589,6 +607,9 @@ static BaseType_t prvCreateIdleTasks( void );
589607 * - If a task is unpinned, check the scheduler suspension state on both cores.
590608 * The task can be scheduled if the scheduler is not suspended on either of
591609 * the cores.
610+ *
611+ * @note This function must be called from a critical section (where the kernel
612+ * lock is taken).
592613 */
593614#if ( configNUMBER_OF_CORES > 1 )
594615
@@ -772,6 +793,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
772793 UBaseType_t uxTaskPriority ,
773794 BaseType_t xYieldEqualPriority )
774795 {
796+ /* This function must be called from a critical section (where the kernel
797+ * lock is taken). */
798+
775799 configASSERT ( uxTaskPriority < configMAX_PRIORITIES );
776800
777801 /* Save core ID as we can no longer be preempted. */
@@ -825,6 +849,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
825849
826850 static BaseType_t prvCheckTaskCanBeScheduledSMP ( TCB_t * pxTCB )
827851 {
852+ /* This function must be called from a critical section (where the kernel
853+ * lock is taken). */
854+
828855 BaseType_t xReturn ;
829856
830857 if ( pxTCB -> xCoreID == tskNO_AFFINITY )
@@ -2462,22 +2489,29 @@ void vTaskEndScheduler( void )
24622489
24632490void vTaskSuspendAll ( void )
24642491{
2465- /* A critical section is not required as the variable is of type
2492+ /* For SMP, we need to take the kernel lock here as we are about to access
2493+ * kernel data structures.
2494+ *
2495+ * For single-core, a critical section is not required as the variable is of type
24662496 * BaseType_t. Please read Richard Barry's reply in the following link to a
24672497 * post in the FreeRTOS support forum before reporting this as a bug! -
24682498 * https://goo.gl/wu4acr */
2499+ prvENTER_CRITICAL_SMP_ONLY ( & xKernelLock );
2500+ {
2501+ /* portSOFTWARE_BARRIER() is only implemented for emulated/simulated ports that
2502+ * do not otherwise exhibit real time behaviour. */
2503+ portSOFTWARE_BARRIER ();
24692504
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 () ];
2505+ /* The scheduler is suspended if uxSchedulerSuspended is non-zero. An increment
2506+ * is used to allow calls to vTaskSuspendAll() to nest. */
2507+ ++ uxSchedulerSuspended [ portGET_CORE_ID () ];
24772508
2478- /* Enforces ordering for ports and optimised compilers that may otherwise place
2479- * the above increment elsewhere. */
2480- portMEMORY_BARRIER ();
2509+ /* Enforces ordering for ports and optimised compilers that may otherwise place
2510+ * the above increment elsewhere. */
2511+ portMEMORY_BARRIER ();
2512+ }
2513+ /* Release the previously taken kernel lock. */
2514+ prvEXIT_CRITICAL_SMP_ONLY ( & xKernelLock );
24812515}
24822516/*----------------------------------------------------------*/
24832517
0 commit comments