From 363e80bfdc34f057d1026e9eb0ee660e799a76f9 Mon Sep 17 00:00:00 2001 From: Darian Leung Date: Sun, 16 Jun 2024 00:40:11 +0800 Subject: [PATCH] feat(freertos/smp): Add granular locking port macros checks Adds the required checks for granular locking port macros. Port Config: - portUSING_GRANULAR_LOCKS to enable granular locks - portCRITICAL_NESTING_IN_TCB should be disabled Granular Locking Port Macros: - Spinlocks - portSPINLOCK_TYPE - portINIT_SPINLOCK( pxSpinlock ) - portINIT_SPINLOCK_STATIC - Locking - portGET_SPINLOCK() - portRELEASE_SPINLOCK() Co-authored-by: Sudeep Mohanty --- include/FreeRTOS.h | 171 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 165 insertions(+), 6 deletions(-) diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h index fca33af3c..d3a76c79a 100644 --- a/include/FreeRTOS.h +++ b/include/FreeRTOS.h @@ -369,6 +369,10 @@ #define portCRITICAL_NESTING_IN_TCB 0 #endif +#ifndef portUSING_GRANULAR_LOCKS + #define portUSING_GRANULAR_LOCKS 0 +#endif + #ifndef configMAX_TASK_NAME_LEN #define configMAX_TASK_NAME_LEN 16 #endif @@ -458,7 +462,7 @@ #ifndef portRELEASE_TASK_LOCK - #if ( configNUMBER_OF_CORES == 1 ) + #if ( ( portUSING_GRANULAR_LOCKS == 1 ) || ( configNUMBER_OF_CORES == 1 ) ) #define portRELEASE_TASK_LOCK( xCoreID ) #else #error portRELEASE_TASK_LOCK is required in SMP @@ -468,7 +472,7 @@ #ifndef portGET_TASK_LOCK - #if ( configNUMBER_OF_CORES == 1 ) + #if ( ( portUSING_GRANULAR_LOCKS == 1 ) || ( configNUMBER_OF_CORES == 1 ) ) #define portGET_TASK_LOCK( xCoreID ) #else #error portGET_TASK_LOCK is required in SMP @@ -478,7 +482,7 @@ #ifndef portRELEASE_ISR_LOCK - #if ( configNUMBER_OF_CORES == 1 ) + #if ( ( portUSING_GRANULAR_LOCKS == 1 ) || ( configNUMBER_OF_CORES == 1 ) ) #define portRELEASE_ISR_LOCK( xCoreID ) #else #error portRELEASE_ISR_LOCK is required in SMP @@ -488,7 +492,7 @@ #ifndef portGET_ISR_LOCK - #if ( configNUMBER_OF_CORES == 1 ) + #if ( ( portUSING_GRANULAR_LOCKS == 1 ) || ( configNUMBER_OF_CORES == 1 ) ) #define portGET_ISR_LOCK( xCoreID ) #else #error portGET_ISR_LOCK is required in SMP @@ -496,6 +500,30 @@ #endif /* portGET_ISR_LOCK */ +#ifndef portRELEASE_SPINLOCK + + #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) + #error portRELEASE_SPINLOCK is required for granular locking + #endif + +#endif + +#ifndef portGET_SPINLOCK + + #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) + #error portGET_SPINLOCK is required for granular locking + #endif + +#endif + +#ifndef portCHECK_IF_IN_ISR + + #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) + #error portCHECK_IF_IN_ISR is required for granular locking + #endif + +#endif + #ifndef portENTER_CRITICAL_FROM_ISR #if ( configNUMBER_OF_CORES > 1 ) @@ -512,6 +540,126 @@ #endif +#ifndef portENTER_CRITICAL_DATA_GROUP + + #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) + #error portENTER_CRITICAL_DATA_GROUP is required for SMP with granular locking feature enabled + #endif + +#endif + +#ifndef portEXIT_CRITICAL_DATA_GROUP + + #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) + #error portEXIT_CRITICAL_DATA_GROUP is required for SMP with granular locking feature enabled + #endif + +#endif + +#ifndef portENTER_CRITICAL_DATA_GROUP_FROM_ISR + + #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) + #error portENTER_CRITICAL_DATA_GROUP_FROM_ISR is required for SMP with granular locking feature enabled + #endif + +#endif + +#ifndef portEXIT_CRITICAL_DATA_GROUP_FROM_ISR + + #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) + #error portEXIT_CRITICAL_DATA_GROUP_FROM_ISR is required for SMP with granular locking feature enabled + #endif + +#endif + +#ifndef portSPINLOCK_TYPE + + #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) + #error portSPINLOCK_TYPE is required for SMP with granular locking feature enabled + #endif + +#endif + +#ifndef portINIT_EVENT_GROUP_TASK_SPINLOCK + + #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) + #error portINIT_EVENT_GROUP_TASK_SPINLOCK is required for granular locking + #endif + +#endif + +#ifndef portINIT_EVENT_GROUP_ISR_SPINLOCK + + #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) + #error portINIT_EVENT_GROUP_ISR_SPINLOCK is required for granular locking + #endif + +#endif + +#ifndef portINIT_QUEUE_TASK_SPINLOCK + + #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) + #error portINIT_QUEUE_TASK_SPINLOCK is required for granular locking + #endif + +#endif + +#ifndef portINIT_QUEUE_ISR_SPINLOCK + + #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) + #error portINIT_QUEUE_ISR_SPINLOCK is required for granular locking + #endif + +#endif + +#ifndef portINIT_STREAM_BUFFER_TASK_SPINLOCK + + #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) + #error portINIT_STREAM_BUFFER_TASK_SPINLOCK is required for granular locking + #endif + +#endif + +#ifndef portINIT_STREAM_BUFFER_ISR_SPINLOCK + + #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) + #error portINIT_STREAM_BUFFER_ISR_SPINLOCK is required for granular locking + #endif + +#endif + +#ifndef portINIT_KERNEL_TASK_SPINLOCK_STATIC + + #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) + #error portINIT_KERNEL_TASK_SPINLOCK_STATIC is required for granular locking + #endif + +#endif + +#ifndef portINIT_KERNEL_ISR_SPINLOCK_STATIC + + #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) + #error portINIT_KERNEL_ISR_SPINLOCK_STATIC is required for granular locking + #endif + +#endif + +#ifndef portINIT_TIMERS_TASK_SPINLOCK_STATIC + + #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) + #error portINIT_TIMERS_TASK_SPINLOCK_STATIC is required for granular locking + #endif + +#endif + +#ifndef portINIT_TIMERS_ISR_SPINLOCK_STATIC + + #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) + #error portINIT_TIMERS_ISR_SPINLOCK_STATIC is required for granular locking + #endif + +#endif + #ifndef configUSE_CORE_AFFINITY #define configUSE_CORE_AFFINITY 0 #endif /* configUSE_CORE_AFFINITY */ @@ -2914,6 +3062,12 @@ #error configUSE_CORE_AFFINITY is not supported in single core FreeRTOS #endif +/* Granular locking relies on the per-task preemption disable count to defer + * state changes and to decide whether a core can be requested to yield. */ +#if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) && ( configUSE_TASK_PREEMPTION_DISABLE != 1 ) ) + #error configUSE_TASK_PREEMPTION_DISABLE must be set to 1 to use granular locks +#endif + #if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_PORT_OPTIMISED_TASK_SELECTION != 0 ) ) #error configUSE_PORT_OPTIMISED_TASK_SELECTION is not supported in SMP FreeRTOS #endif @@ -2927,8 +3081,13 @@ /* Either variables of tick type cannot be read atomically, or * portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when * the tick count is returned to the standard critical section macros. */ - #define portTICK_TYPE_ENTER_CRITICAL() portENTER_CRITICAL() - #define portTICK_TYPE_EXIT_CRITICAL() portEXIT_CRITICAL() + #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) + #define portTICK_TYPE_ENTER_CRITICAL() portENTER_CRITICAL_DATA_GROUP( &xTaskSpinlock, &xISRSpinlock ) + #define portTICK_TYPE_EXIT_CRITICAL() portEXIT_CRITICAL_DATA_GROUP( &xTaskSpinlock, &xISRSpinlock ) + #else /* #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) */ + #define portTICK_TYPE_ENTER_CRITICAL() portENTER_CRITICAL() + #define portTICK_TYPE_EXIT_CRITICAL() portEXIT_CRITICAL() + #endif /* #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) */ #define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR() #define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( ( x ) ) #else