From cb637b93189c19fe392c06343ec37bdd25a03793 Mon Sep 17 00:00:00 2001 From: Darian Leung Date: Sun, 16 Jun 2024 01:13:43 +0800 Subject: [PATCH] change(freertos/smp): Update timers.c locking Updated timers.c to use granular locking - Added xTaskSpinlock and xISRSpinlock - Replaced critical section macros with data group critical section macros such as taskENTER/EXIT_CRITICAL() with tmrENTER/EXIT_CRITICAL(). - Added vTimerEnterCritical() and vTimerExitCritical() to map to the data group critical section macros. Co-authored-by: Sudeep Mohanty --- timers.c | 48 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/timers.c b/timers.c index 1bc40bc46..d63667e8d 100644 --- a/timers.c +++ b/timers.c @@ -79,6 +79,17 @@ #define tmrSTATUS_IS_STATICALLY_ALLOCATED ( 0x02U ) #define tmrSTATUS_IS_AUTORELOAD ( 0x04U ) +/* + * Macros to mark the start and end of a critical code region. + */ + #if ( portUSING_GRANULAR_LOCKS == 1 ) + #define tmrENTER_CRITICAL() taskDATA_GROUP_ENTER_CRITICAL( &xTimerDataGroupLocks ) + #define tmrEXIT_CRITICAL() taskDATA_GROUP_EXIT_CRITICAL( &xTimerDataGroupLocks ) + #else /* #if ( portUSING_GRANULAR_LOCKS == 1 ) */ + #define tmrENTER_CRITICAL() taskENTER_CRITICAL() + #define tmrEXIT_CRITICAL() taskEXIT_CRITICAL() + #endif /* #if ( portUSING_GRANULAR_LOCKS == 1 ) */ + /* The definition of the timers themselves. */ typedef struct tmrTimerControl /* The old naming convention is used to prevent breaking kernel aware debuggers. */ { @@ -149,6 +160,19 @@ PRIVILEGED_DATA static QueueHandle_t xTimerQueue = NULL; PRIVILEGED_DATA static TaskHandle_t xTimerTaskHandle = NULL; + #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) + PRIVILEGED_DATA static struct + { + portSPINLOCK_TYPE xTaskSpinlock; + portSPINLOCK_TYPE xISRSpinlock; + } + xTimerDataGroupLocks = + { + .xTaskSpinlock = portINIT_SPINLOCK_STATIC, + .xISRSpinlock = portINIT_SPINLOCK_STATIC + }; + #endif /* #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) */ + /*-----------------------------------------------------------*/ /* @@ -572,7 +596,7 @@ traceENTER_vTimerSetReloadMode( xTimer, xAutoReload ); configASSERT( xTimer ); - taskENTER_CRITICAL(); + tmrENTER_CRITICAL(); { if( xAutoReload != pdFALSE ) { @@ -583,7 +607,7 @@ pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_AUTORELOAD ); } } - taskEXIT_CRITICAL(); + tmrEXIT_CRITICAL(); traceRETURN_vTimerSetReloadMode(); } @@ -597,7 +621,7 @@ traceENTER_xTimerGetReloadMode( xTimer ); configASSERT( xTimer ); - portBASE_TYPE_ENTER_CRITICAL(); + tmrENTER_CRITICAL(); { if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) == 0U ) { @@ -610,7 +634,7 @@ xReturn = pdTRUE; } } - portBASE_TYPE_EXIT_CRITICAL(); + tmrEXIT_CRITICAL(); traceRETURN_xTimerGetReloadMode( xReturn ); @@ -1116,7 +1140,7 @@ /* Check that the list from which active timers are referenced, and the * queue used to communicate with the timer service, have been * initialised. */ - taskENTER_CRITICAL(); + tmrENTER_CRITICAL(); { if( xTimerQueue == NULL ) { @@ -1158,7 +1182,7 @@ mtCOVERAGE_TEST_MARKER(); } } - taskEXIT_CRITICAL(); + tmrEXIT_CRITICAL(); } /*-----------------------------------------------------------*/ @@ -1172,7 +1196,7 @@ configASSERT( xTimer ); /* Is the timer in the list of active timers? */ - portBASE_TYPE_ENTER_CRITICAL(); + tmrENTER_CRITICAL(); { if( ( pxTimer->ucStatus & tmrSTATUS_IS_ACTIVE ) == 0U ) { @@ -1183,7 +1207,7 @@ xReturn = pdTRUE; } } - portBASE_TYPE_EXIT_CRITICAL(); + tmrEXIT_CRITICAL(); traceRETURN_xTimerIsTimerActive( xReturn ); @@ -1200,11 +1224,11 @@ configASSERT( xTimer ); - taskENTER_CRITICAL(); + tmrENTER_CRITICAL(); { pvReturn = pxTimer->pvTimerID; } - taskEXIT_CRITICAL(); + tmrEXIT_CRITICAL(); traceRETURN_pvTimerGetTimerID( pvReturn ); @@ -1221,11 +1245,11 @@ configASSERT( xTimer ); - taskENTER_CRITICAL(); + tmrENTER_CRITICAL(); { pxTimer->pvTimerID = pvNewID; } - taskEXIT_CRITICAL(); + tmrEXIT_CRITICAL(); traceRETURN_vTimerSetTimerID(); }