@@ -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 {
@@ -6968,7 +7009,7 @@ static void prvResetNextTaskUnblockTime( void )
69687009#endif /* #if ( ( portCRITICAL_NESTING_IN_TCB == 1 ) && ( configNUMBER_OF_CORES == 1 ) ) */
69697010/*-----------------------------------------------------------*/
69707011
6971- #if ( configNUMBER_OF_CORES > 1 )
7012+ #if ( ( portUSING_GRANULAR_LOCKS == 0 ) && ( configNUMBER_OF_CORES > 1 ) )
69727013
69737014 void vTaskEnterCritical ( void )
69747015 {
@@ -7014,11 +7055,10 @@ static void prvResetNextTaskUnblockTime( void )
70147055 traceRETURN_vTaskEnterCritical ();
70157056 }
70167057
7017- #endif /* #if ( configNUMBER_OF_CORES > 1 ) */
7018-
7058+ #endif /* #if ( ( portUSING_GRANULAR_LOCKS == 0 ) && ( configNUMBER_OF_CORES > 1 ) ) */
70197059/*-----------------------------------------------------------*/
70207060
7021- #if ( configNUMBER_OF_CORES > 1 )
7061+ #if ( ( portUSING_GRANULAR_LOCKS == 0 ) && ( configNUMBER_OF_CORES > 1 ) )
70227062
70237063 UBaseType_t vTaskEnterCriticalFromISR ( void )
70247064 {
@@ -7047,7 +7087,7 @@ static void prvResetNextTaskUnblockTime( void )
70477087 return uxSavedInterruptStatus ;
70487088 }
70497089
7050- #endif /* #if ( configNUMBER_OF_CORES > 1 ) */
7090+ #endif /* #if ( ( portUSING_GRANULAR_LOCKS == 0 ) && ( configNUMBER_OF_CORES > 1 ) ) */
70517091/*-----------------------------------------------------------*/
70527092
70537093#if ( ( portCRITICAL_NESTING_IN_TCB == 1 ) && ( configNUMBER_OF_CORES == 1 ) )
@@ -7095,7 +7135,7 @@ static void prvResetNextTaskUnblockTime( void )
70957135#endif /* #if ( ( portCRITICAL_NESTING_IN_TCB == 1 ) && ( configNUMBER_OF_CORES == 1 ) ) */
70967136/*-----------------------------------------------------------*/
70977137
7098- #if ( configNUMBER_OF_CORES > 1 )
7138+ #if ( ( portUSING_GRANULAR_LOCKS == 0 ) && ( configNUMBER_OF_CORES > 1 ) )
70997139
71007140 void vTaskExitCritical ( void )
71017141 {
@@ -7153,10 +7193,10 @@ static void prvResetNextTaskUnblockTime( void )
71537193 traceRETURN_vTaskExitCritical ();
71547194 }
71557195
7156- #endif /* #if ( configNUMBER_OF_CORES > 1 ) */
7196+ #endif /* #if ( ( portUSING_GRANULAR_LOCKS == 0 ) && ( configNUMBER_OF_CORES > 1 ) ) */
71577197/*-----------------------------------------------------------*/
71587198
7159- #if ( configNUMBER_OF_CORES > 1 )
7199+ #if ( ( portUSING_GRANULAR_LOCKS == 0 ) && ( configNUMBER_OF_CORES > 1 ) )
71607200
71617201 void vTaskExitCriticalFromISR ( UBaseType_t uxSavedInterruptStatus )
71627202 {
@@ -7195,7 +7235,29 @@ static void prvResetNextTaskUnblockTime( void )
71957235 traceRETURN_vTaskExitCriticalFromISR ();
71967236 }
71977237
7198- #endif /* #if ( configNUMBER_OF_CORES > 1 ) */
7238+ #endif /* #if ( ( portUSING_GRANULAR_LOCKS == 0 ) && ( configNUMBER_OF_CORES > 1 ) ) */
7239+ /*-----------------------------------------------------------*/
7240+
7241+ #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) )
7242+
7243+ BaseType_t xTaskUnlockCanYield ( void )
7244+ {
7245+ BaseType_t xReturn ;
7246+ BaseType_t xCoreID = portGET_CORE_ID ();
7247+
7248+ if ( ( xYieldPendings [ xCoreID ] == pdTRUE ) && ( uxSchedulerSuspended == pdFALSE ) && ( pxCurrentTCBs [ xCoreID ]-> xPreemptionDisable == pdFALSE ) )
7249+ {
7250+ xReturn = pdTRUE ;
7251+ }
7252+ else
7253+ {
7254+ xReturn = pdFALSE ;
7255+ }
7256+
7257+ return xReturn ;
7258+ }
7259+
7260+ #endif /* #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) */
71997261/*-----------------------------------------------------------*/
72007262
72017263#if ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 )
0 commit comments