@@ -488,7 +488,7 @@ PRIVILEGED_DATA static volatile TickType_t xTickCount = ( TickType_t ) configINI
488488PRIVILEGED_DATA static volatile UBaseType_t uxTopReadyPriority = tskIDLE_PRIORITY ;
489489PRIVILEGED_DATA static volatile BaseType_t xSchedulerRunning = pdFALSE ;
490490PRIVILEGED_DATA static volatile TickType_t xPendedTicks = ( TickType_t ) 0U ;
491- PRIVILEGED_DATA static volatile BaseType_t xYieldPendings [ configNUMBER_OF_CORES ] = { pdFALSE };
491+ PRIVILEGED_DATA volatile BaseType_t xYieldPendings [ configNUMBER_OF_CORES ] = { pdFALSE };
492492PRIVILEGED_DATA static volatile BaseType_t xNumOfOverflows = ( BaseType_t ) 0 ;
493493PRIVILEGED_DATA static UBaseType_t uxTaskNumber = ( UBaseType_t ) 0U ;
494494PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime = ( TickType_t ) 0U ; /* Initialised to portMAX_DELAY before the scheduler starts. */
@@ -522,6 +522,11 @@ PRIVILEGED_DATA static volatile configRUN_TIME_COUNTER_TYPE ulTotalRunTime[ conf
522522
523523#endif
524524
525+ #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) )
526+ PRIVILEGED_DATA static portSPINLOCK_TYPE xTaskSpinlock = portINIT_KERNEL_TASK_SPINLOCK_STATIC ;
527+ PRIVILEGED_DATA static portSPINLOCK_TYPE xISRSpinlock = portINIT_KERNEL_ISR_SPINLOCK_STATIC ;
528+ #endif /* #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) */
529+
525530/*-----------------------------------------------------------*/
526531
527532/* File private functions. --------------------------------*/
@@ -531,14 +536,14 @@ PRIVILEGED_DATA static volatile configRUN_TIME_COUNTER_TYPE ulTotalRunTime[ conf
531536 */
532537static BaseType_t prvCreateIdleTasks ( void );
533538
534- #if ( configNUMBER_OF_CORES > 1 )
539+ #if ( ( portUSING_GRANULAR_LOCKS == 0 ) && ( configNUMBER_OF_CORES > 1 ) )
535540
536541/*
537542 * Checks to see if another task moved the current task out of the ready
538543 * list while it was waiting to enter a critical section and yields, if so.
539544 */
540545 static void prvCheckForRunStateChange ( void );
541- #endif /* #if ( configNUMBER_OF_CORES > 1 ) */
546+ #endif /* #if ( ( portUSING_GRANULAR_LOCKS == 0 ) && ( configNUMBER_OF_CORES > 1 ) ) */
542547
543548#if ( configNUMBER_OF_CORES > 1 )
544549
@@ -802,7 +807,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
802807#endif /* #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) */
803808/*-----------------------------------------------------------*/
804809
805- #if ( configNUMBER_OF_CORES > 1 )
810+ #if ( ( portUSING_GRANULAR_LOCKS == 0 ) && ( configNUMBER_OF_CORES > 1 ) )
806811 static void prvCheckForRunStateChange ( void )
807812 {
808813 UBaseType_t uxPrevCriticalNesting ;
@@ -863,7 +868,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
863868 }
864869 }
865870 }
866- #endif /* #if ( configNUMBER_OF_CORES > 1 ) */
871+ #endif /* #if ( ( portUSING_GRANULAR_LOCKS == 0 ) && ( configNUMBER_OF_CORES > 1 ) ) */
867872
868873/*-----------------------------------------------------------*/
869874
@@ -3871,26 +3876,45 @@ void vTaskSuspendAll( void )
38713876 * do not otherwise exhibit real time behaviour. */
38723877 portSOFTWARE_BARRIER ();
38733878
3874- portGET_TASK_LOCK ();
3875-
3876- /* uxSchedulerSuspended is increased after prvCheckForRunStateChange. The
3877- * purpose is to prevent altering the variable when fromISR APIs are readying
3878- * it. */
3879- if ( uxSchedulerSuspended == 0U )
3879+ #if ( portUSING_GRANULAR_LOCKS == 1 )
38803880 {
3881- prvCheckForRunStateChange ();
3881+ portGET_SPINLOCK ( & xTaskSpinlock );
3882+ portGET_SPINLOCK ( & xISRSpinlock );
3883+
3884+ /* Increment xPreemptionDisable to prevent preemption and also
3885+ * track whether to yield in xTaskResumeAll(). */
3886+ pxCurrentTCBs [ portGET_CORE_ID () ]-> xPreemptionDisable ++ ;
3887+
3888+ /* The scheduler is suspended if uxSchedulerSuspended is non-zero. An increment
3889+ * is used to allow calls to vTaskSuspendAll() to nest. */
3890+ ++ uxSchedulerSuspended ;
3891+
3892+ portRELEASE_SPINLOCK ( & xISRSpinlock );
38823893 }
3883- else
3894+ # else /* #if ( portUSING_GRANULAR_LOCKS == 1 ) */
38843895 {
3885- mtCOVERAGE_TEST_MARKER ();
3886- }
3896+ portGET_TASK_LOCK ();
38873897
3888- portGET_ISR_LOCK ();
3898+ /* uxSchedulerSuspended is increased after prvCheckForRunStateChange. The
3899+ * purpose is to prevent altering the variable when fromISR APIs are readying
3900+ * it. */
3901+ if ( uxSchedulerSuspended == 0U )
3902+ {
3903+ prvCheckForRunStateChange ();
3904+ }
3905+ else
3906+ {
3907+ mtCOVERAGE_TEST_MARKER ();
3908+ }
38893909
3890- /* The scheduler is suspended if uxSchedulerSuspended is non-zero. An increment
3891- * is used to allow calls to vTaskSuspendAll() to nest. */
3892- ++ uxSchedulerSuspended ;
3893- portRELEASE_ISR_LOCK ();
3910+ portGET_ISR_LOCK ();
3911+
3912+ /* The scheduler is suspended if uxSchedulerSuspended is non-zero. An increment
3913+ * is used to allow calls to vTaskSuspendAll() to nest. */
3914+ ++ uxSchedulerSuspended ;
3915+ portRELEASE_ISR_LOCK ();
3916+ }
3917+ #endif /* #if ( portUSING_GRANULAR_LOCKS == 1 ) */
38943918
38953919 portCLEAR_INTERRUPT_MASK ( ulState );
38963920 }
@@ -3996,7 +4020,24 @@ BaseType_t xTaskResumeAll( void )
39964020 configASSERT ( uxSchedulerSuspended != 0U );
39974021
39984022 uxSchedulerSuspended = ( UBaseType_t ) ( uxSchedulerSuspended - 1U );
3999- portRELEASE_TASK_LOCK ();
4023+ #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) )
4024+ {
4025+ configASSERT ( pxCurrentTCBs [ portGET_CORE_ID () ]-> xPreemptionDisable > 0 );
4026+
4027+ /* Decrement xPreemptionDisable. If 0, it means this we are not
4028+ * in a nested suspension scenario, thus this function and yield
4029+ * if necessary. */
4030+ pxCurrentTCBs [ portGET_CORE_ID () ]-> xPreemptionDisable -- ;
4031+
4032+ /* Release the kernel's task spinlock that was held throughout
4033+ * the kernel suspension. */
4034+ portRELEASE_SPINLOCK ( & xTaskSpinlock );
4035+ }
4036+ #else /* #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) */
4037+ {
4038+ portRELEASE_TASK_LOCK ();
4039+ }
4040+ #endif /* #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) */
40004041
40014042 if ( uxSchedulerSuspended == ( UBaseType_t ) 0U )
40024043 {
@@ -6986,7 +7027,7 @@ static void prvResetNextTaskUnblockTime( void )
69867027#endif /* #if ( ( portCRITICAL_NESTING_IN_TCB == 1 ) && ( configNUMBER_OF_CORES == 1 ) ) */
69877028/*-----------------------------------------------------------*/
69887029
6989- #if ( configNUMBER_OF_CORES > 1 )
7030+ #if ( ( portUSING_GRANULAR_LOCKS == 0 ) && ( configNUMBER_OF_CORES > 1 ) )
69907031
69917032 void vTaskEnterCritical ( void )
69927033 {
@@ -7032,11 +7073,10 @@ static void prvResetNextTaskUnblockTime( void )
70327073 traceRETURN_vTaskEnterCritical ();
70337074 }
70347075
7035- #endif /* #if ( configNUMBER_OF_CORES > 1 ) */
7036-
7076+ #endif /* #if ( ( portUSING_GRANULAR_LOCKS == 0 ) && ( configNUMBER_OF_CORES > 1 ) ) */
70377077/*-----------------------------------------------------------*/
70387078
7039- #if ( configNUMBER_OF_CORES > 1 )
7079+ #if ( ( portUSING_GRANULAR_LOCKS == 0 ) && ( configNUMBER_OF_CORES > 1 ) )
70407080
70417081 UBaseType_t vTaskEnterCriticalFromISR ( void )
70427082 {
@@ -7065,7 +7105,7 @@ static void prvResetNextTaskUnblockTime( void )
70657105 return uxSavedInterruptStatus ;
70667106 }
70677107
7068- #endif /* #if ( configNUMBER_OF_CORES > 1 ) */
7108+ #endif /* #if ( ( portUSING_GRANULAR_LOCKS == 0 ) && ( configNUMBER_OF_CORES > 1 ) ) */
70697109/*-----------------------------------------------------------*/
70707110
70717111#if ( ( portCRITICAL_NESTING_IN_TCB == 1 ) && ( configNUMBER_OF_CORES == 1 ) )
@@ -7113,7 +7153,7 @@ static void prvResetNextTaskUnblockTime( void )
71137153#endif /* #if ( ( portCRITICAL_NESTING_IN_TCB == 1 ) && ( configNUMBER_OF_CORES == 1 ) ) */
71147154/*-----------------------------------------------------------*/
71157155
7116- #if ( configNUMBER_OF_CORES > 1 )
7156+ #if ( ( portUSING_GRANULAR_LOCKS == 0 ) && ( configNUMBER_OF_CORES > 1 ) )
71177157
71187158 void vTaskExitCritical ( void )
71197159 {
@@ -7171,10 +7211,10 @@ static void prvResetNextTaskUnblockTime( void )
71717211 traceRETURN_vTaskExitCritical ();
71727212 }
71737213
7174- #endif /* #if ( configNUMBER_OF_CORES > 1 ) */
7214+ #endif /* #if ( ( portUSING_GRANULAR_LOCKS == 0 ) && ( configNUMBER_OF_CORES > 1 ) ) */
71757215/*-----------------------------------------------------------*/
71767216
7177- #if ( configNUMBER_OF_CORES > 1 )
7217+ #if ( ( portUSING_GRANULAR_LOCKS == 0 ) && ( configNUMBER_OF_CORES > 1 ) )
71787218
71797219 void vTaskExitCriticalFromISR ( UBaseType_t uxSavedInterruptStatus )
71807220 {
@@ -7213,7 +7253,29 @@ static void prvResetNextTaskUnblockTime( void )
72137253 traceRETURN_vTaskExitCriticalFromISR ();
72147254 }
72157255
7216- #endif /* #if ( configNUMBER_OF_CORES > 1 ) */
7256+ #endif /* #if ( ( portUSING_GRANULAR_LOCKS == 0 ) && ( configNUMBER_OF_CORES > 1 ) ) */
7257+ /*-----------------------------------------------------------*/
7258+
7259+ #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) )
7260+
7261+ BaseType_t xTaskUnlockCanYield ( void )
7262+ {
7263+ BaseType_t xReturn ;
7264+ BaseType_t xCoreID = portGET_CORE_ID ();
7265+
7266+ if ( ( xYieldPendings [ xCoreID ] == pdTRUE ) && ( uxSchedulerSuspended == pdFALSE ) && ( pxCurrentTCBs [ xCoreID ]-> xPreemptionDisable == pdFALSE ) )
7267+ {
7268+ xReturn = pdTRUE ;
7269+ }
7270+ else
7271+ {
7272+ xReturn = pdFALSE ;
7273+ }
7274+
7275+ return xReturn ;
7276+ }
7277+
7278+ #endif /* #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) */
72177279/*-----------------------------------------------------------*/
72187280
72197281#if ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 )
0 commit comments