Compare commits

..

8 commits

Author SHA1 Message Date
Sudeep Mohanty 35987eb280
Merge 71c4c6d89a into 62bd622ffc 2025-06-10 13:54:32 +00:00
Darian Leung 71c4c6d89a feat(freertos/smp): Add Granular Locking V4 proposal documents
Co-authored-by: Sudeep Mohanty <sudeep.mohanty@espressif.com>
2025-06-10 15:54:16 +02:00
Darian Leung 7f8416db94 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 <sudeep.mohanty@espressif.com>
2025-06-10 15:54:10 +02:00
Darian Leung ab8600effc change(freertos/smp): Update stream_buffer.c locking
Updated stream_buffer.c to use granular locking

- Added xTaskSpinlock and xISRSpinlock
- Replaced critical section macros with data group critical section macros
such as taskENTER/EXIT_CRITICAL/_FROM_ISR() with sbENTER/EXIT_CRITICAL_FROM_ISR().
- Added vStreambuffersEnterCritical/FromISR() and
  vStreambuffersExitCritical/FromISR() to map to the data group critical
section macros.
- Added prvLockStreamBufferForTasks() and prvUnlockStreamBufferForTasks() to suspend the stream
buffer when executing non-deterministic code.

Co-authored-by: Sudeep Mohanty <sudeep.mohanty@espressif.com>
2025-06-10 15:54:04 +02:00
Darian Leung 3184393420 change(freertos/smp): Update event_groups.c locking
Updated event_groups.c to use granular locking

- Added xTaskSpinlock and xISRSpinlock
- Replaced critical section macros with data group critical section macros
such as taskENTER/EXIT_CRITICAL/_FROM_ISR() with event_groupsENTER/EXIT_CRITICAL/_FROM_ISR().
- Added vEventGroupsEnterCritical/FromISR() and
  vEventGroupsExitCriti/FromISR() functions that map to the data group
critical section macros.
- Added prvLockEventGroupForTasks() and prvUnlockEventGroupForTasks() to suspend the event
group when executing non-deterministic code.
- xEventGroupSetBits() and vEventGroupDelete() accesses the kernel data group
directly. Thus, added vTaskSuspendAll()/xTaskResumeAll() to these fucntions.

Co-authored-by: Sudeep Mohanty <sudeep.mohanty@espressif.com>
2025-06-10 15:53:57 +02:00
Darian Leung c712a63ce8 change(freertos/smp): Update queue.c locking
Updated queue.c to use granular locking

- Added xTaskSpinlock and xISRSpinlock
- Replaced  critical section macros with data group critical section macros
such as taskENTER/EXIT_CRITICAL/_FROM_ISR() with queueENTER/EXIT_CRITICAL_FROM_ISR().
- Added vQueueEnterCritical/FromISR() and vQueueExitCritical/FromISR()
  which map to the data group critical section macros.
- Added prvLockQueueForTasks() and prvUnlockQueueForTasks() as the granular locking equivalents
to prvLockQueue() and prvUnlockQueue() respectively

Co-authored-by: Sudeep Mohanty <sudeep.mohanty@espressif.com>
2025-06-10 15:53:50 +02:00
Darian Leung e584634e1f change(freertos/smp): Update tasks.c locking
Updated critical section macros with granular locks.

Some tasks.c API relied on their callers to enter critical sections. This
assumption no longer works under granular locking. Critical sections added to
the following functions:

- `vTaskInternalSetTimeOutState()`
- `xTaskIncrementTick()`
- `vTaskSwitchContext()`
- `xTaskRemoveFromEventList()`
- `vTaskInternalSetTimeOutState()`
- `eTaskConfirmSleepModeStatus()`
- `xTaskPriorityDisinherit()`
- `pvTaskIncrementMutexHeldCount()`

Added missing suspensions to the following functions:

- `vTaskPlaceOnEventList()`
- `vTaskPlaceOnUnorderedEventList()`
- `vTaskPlaceOnEventListRestricted()`

Fixed the locking in vTaskSwitchContext()

vTaskSwitchContext() must aquire both kernel locks, viz., task lock and
ISR lock. This is because, vTaskSwitchContext() can be called from
either task context or ISR context. Also, vTaskSwitchContext() must not
alter the interrupt state prematurely.

Co-authored-by: Sudeep Mohanty <sudeep.mohanty@espressif.com>
2025-06-10 15:53:50 +02:00
Darian Leung 21382c3def feat(granular_locks): Add granular locking functions
- Updated prvCheckForRunStateChange() for granular locks
- Updated vTaskSuspendAll() and xTaskResumeAll()
    - Now holds the xTaskSpinlock during kernel suspension
    - Increments/decrements xPreemptionDisable. Only yields when 0, thus allowing
    for nested suspensions across different data groups

Co-authored-by: Sudeep Mohanty <sudeep.mohanty@espressif.com>
2025-06-10 15:53:09 +02:00
5 changed files with 100 additions and 110 deletions

View file

@ -76,13 +76,13 @@
* Macros to mark the start and end of a critical code region. * Macros to mark the start and end of a critical code region.
*/ */
#if ( portUSING_GRANULAR_LOCKS == 1 ) #if ( portUSING_GRANULAR_LOCKS == 1 )
#define event_groupsENTER_CRITICAL( pxEventBits ) taskDATA_GROUP_ENTER_CRITICAL( pxEventBits ) #define event_groupsENTER_CRITICAL( pxEventBits ) taskDATA_GROUP_ENTER_CRITICAL( &pxEventBits->xTaskSpinlock, &pxEventBits->xISRSpinlock )
#define event_groupsENTER_CRITICAL_FROM_ISR( pxEventBits ) taskDATA_GROUP_ENTER_CRITICAL_FROM_ISR( pxEventBits ) #define event_groupsENTER_CRITICAL_FROM_ISR( pxEventBits, puxSavedInterruptStatus ) taskDATA_GROUP_ENTER_CRITICAL_FROM_ISR( &pxEventBits->xISRSpinlock, puxSavedInterruptStatus )
#define event_groupsEXIT_CRITICAL( pxEventBits ) taskDATA_GROUP_EXIT_CRITICAL( pxEventBits ) #define event_groupsEXIT_CRITICAL( pxEventBits ) taskDATA_GROUP_EXIT_CRITICAL( &pxEventBits->xTaskSpinlock, &pxEventBits->xISRSpinlock )
#define event_groupsEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus, pxEventBits ) taskDATA_GROUP_EXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus, pxEventBits ) #define event_groupsEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus, pxEventBits ) taskDATA_GROUP_EXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus, &pxEventBits->xISRSpinlock )
#else /* #if ( portUSING_GRANULAR_LOCKS == 1 ) */ #else /* #if ( portUSING_GRANULAR_LOCKS == 1 ) */
#define event_groupsENTER_CRITICAL( pxEventBits ) taskENTER_CRITICAL(); #define event_groupsENTER_CRITICAL( pxEventBits ) taskENTER_CRITICAL();
#define event_groupsENTER_CRITICAL_FROM_ISR( pxEventBits ) taskENTER_CRITICAL_FROM_ISR(); #define event_groupsENTER_CRITICAL_FROM_ISR( pxEventBits, puxSavedInterruptStatus ) do { *( puxSavedInterruptStatus ) = taskENTER_CRITICAL_FROM_ISR(); } while( 0 )
#define event_groupsEXIT_CRITICAL( pxEventBits ) taskEXIT_CRITICAL(); #define event_groupsEXIT_CRITICAL( pxEventBits ) taskEXIT_CRITICAL();
#define event_groupsEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus, pxEventBits ) taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); #define event_groupsEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus, pxEventBits ) taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus );
#endif /* #if ( portUSING_GRANULAR_LOCKS == 1 ) */ #endif /* #if ( portUSING_GRANULAR_LOCKS == 1 ) */
@ -603,7 +603,7 @@
/* MISRA Ref 4.7.1 [Return value shall be checked] */ /* MISRA Ref 4.7.1 [Return value shall be checked] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */
/* coverity[misra_c_2012_directive_4_7_violation] */ /* coverity[misra_c_2012_directive_4_7_violation] */
uxSavedInterruptStatus = event_groupsENTER_CRITICAL_FROM_ISR( pxEventBits ); event_groupsENTER_CRITICAL_FROM_ISR( pxEventBits, &uxSavedInterruptStatus );
{ {
uxReturn = pxEventBits->uxEventBits; uxReturn = pxEventBits->uxEventBits;
} }

View file

@ -292,7 +292,7 @@ typedef enum
* \ingroup GranularLocks * \ingroup GranularLocks
*/ */
#if ( portUSING_GRANULAR_LOCKS == 1 ) #if ( portUSING_GRANULAR_LOCKS == 1 )
#define taskDATA_GROUP_ENTER_CRITICAL( pxDataGroup ) \ #define taskDATA_GROUP_ENTER_CRITICAL( pxTaskSpinlock, pxISRSpinlock ) \
do { \ do { \
/* Disable preemption to avoid task state changes during the critical section. */ \ /* Disable preemption to avoid task state changes during the critical section. */ \
vTaskPreemptionDisable( NULL ); \ vTaskPreemptionDisable( NULL ); \
@ -300,11 +300,11 @@ typedef enum
const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID(); \ const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID(); \
if( portGET_CRITICAL_NESTING_COUNT( xCoreID ) == 0U ) { \ if( portGET_CRITICAL_NESTING_COUNT( xCoreID ) == 0U ) { \
/* Task spinlock is always taken first */ \ /* Task spinlock is always taken first */ \
portGET_SPINLOCK( xCoreID, ( portSPINLOCK_TYPE * ) &( ( pxDataGroup )->xTaskSpinlock ) ); \ portGET_SPINLOCK( xCoreID, ( portSPINLOCK_TYPE * ) pxTaskSpinlock ); \
/* Disable interrupts */ \ /* Disable interrupts */ \
portDISABLE_INTERRUPTS(); \ portDISABLE_INTERRUPTS(); \
/* Take the ISR spinlock next */ \ /* Take the ISR spinlock next */ \
portGET_SPINLOCK( xCoreID, ( portSPINLOCK_TYPE * ) &( ( pxDataGroup )->xISRSpinlock ) ); \ portGET_SPINLOCK( xCoreID, ( portSPINLOCK_TYPE * ) pxISRSpinlock ); \
} \ } \
else \ else \
{ \ { \
@ -325,17 +325,15 @@ typedef enum
* \ingroup GranularLocks * \ingroup GranularLocks
*/ */
#if ( portUSING_GRANULAR_LOCKS == 1 ) #if ( portUSING_GRANULAR_LOCKS == 1 )
#define taskDATA_GROUP_ENTER_CRITICAL_FROM_ISR( pxDataGroup ) \ #define taskDATA_GROUP_ENTER_CRITICAL_FROM_ISR( pxISRSpinlock, puxSavedInterruptStatus ) \
( { \ do { \
UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); \ *( puxSavedInterruptStatus ) = portSET_INTERRUPT_MASK_FROM_ISR(); \
const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID(); \ const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID(); \
/* Take the ISR spinlock */ \ /* Take the ISR spinlock */ \
portGET_SPINLOCK( xCoreID, ( portSPINLOCK_TYPE * ) &( ( pxDataGroup )->xISRSpinlock ) ); \ portGET_SPINLOCK( xCoreID, ( portSPINLOCK_TYPE * ) pxISRSpinlock ); \
/* Increment the critical nesting count */ \ /* Increment the critical nesting count */ \
portINCREMENT_CRITICAL_NESTING_COUNT( xCoreID ); \ portINCREMENT_CRITICAL_NESTING_COUNT( xCoreID ); \
/* Return the previous interrupt status */ \ } while( 0 )
uxSavedInterruptStatus; \
} )
#endif /* #if ( portUSING_GRANULAR_LOCKS == 1 ) */ #endif /* #if ( portUSING_GRANULAR_LOCKS == 1 ) */
/** /**
@ -347,7 +345,7 @@ typedef enum
* \ingroup GranularLocks * \ingroup GranularLocks
*/ */
#if ( portUSING_GRANULAR_LOCKS == 1 ) #if ( portUSING_GRANULAR_LOCKS == 1 )
#define taskDATA_GROUP_EXIT_CRITICAL( pxDataGroup ) \ #define taskDATA_GROUP_EXIT_CRITICAL( pxTaskSpinlock, pxISRSpinlock ) \
do { \ do { \
const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID(); \ const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID(); \
configASSERT( portGET_CRITICAL_NESTING_COUNT( xCoreID ) > 0U ); \ configASSERT( portGET_CRITICAL_NESTING_COUNT( xCoreID ) > 0U ); \
@ -356,11 +354,11 @@ typedef enum
if( portGET_CRITICAL_NESTING_COUNT( xCoreID ) == 0 ) \ if( portGET_CRITICAL_NESTING_COUNT( xCoreID ) == 0 ) \
{ \ { \
/* Release the ISR spinlock */ \ /* Release the ISR spinlock */ \
portRELEASE_SPINLOCK( xCoreID, ( portSPINLOCK_TYPE * ) &( ( pxDataGroup )->xISRSpinlock ) ); \ portRELEASE_SPINLOCK( xCoreID, ( portSPINLOCK_TYPE * ) pxISRSpinlock ); \
/* Enable interrupts */ \ /* Enable interrupts */ \
portENABLE_INTERRUPTS(); \ portENABLE_INTERRUPTS(); \
/* Release the task spinlock */ \ /* Release the task spinlock */ \
portRELEASE_SPINLOCK( xCoreID, ( portSPINLOCK_TYPE * ) &( ( pxDataGroup )->xTaskSpinlock ) ); \ portRELEASE_SPINLOCK( xCoreID, ( portSPINLOCK_TYPE * ) pxTaskSpinlock ); \
} \ } \
else \ else \
{ \ { \
@ -380,17 +378,17 @@ typedef enum
* \ingroup GranularLocks * \ingroup GranularLocks
*/ */
#if ( portUSING_GRANULAR_LOCKS == 1 ) #if ( portUSING_GRANULAR_LOCKS == 1 )
#define taskDATA_GROUP_EXIT_CRITICAL_FROM_ISR( xSavedInterruptStatus, pxDataGroup ) \ #define taskDATA_GROUP_EXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus, pxISRSpinlock ) \
do { \ do { \
const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID(); \ const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID(); \
configASSERT( portGET_CRITICAL_NESTING_COUNT( xCoreID ) > 0U ); \ configASSERT( portGET_CRITICAL_NESTING_COUNT( xCoreID ) > 0U ); \
/* Decrement the critical nesting count */ \ /* Decrement the critical nesting count */ \
portDECREMENT_CRITICAL_NESTING_COUNT( xCoreID ); \ portDECREMENT_CRITICAL_NESTING_COUNT( xCoreID ); \
/* Release the ISR spinlock */ \ /* Release the ISR spinlock */ \
portRELEASE_SPINLOCK( xCoreID, ( portSPINLOCK_TYPE * ) &( pxDataGroup->xISRSpinlock ) ); \ portRELEASE_SPINLOCK( xCoreID, ( portSPINLOCK_TYPE * ) pxISRSpinlock ); \
if( portGET_CRITICAL_NESTING_COUNT( xCoreID ) == 0 ) \ if( portGET_CRITICAL_NESTING_COUNT( xCoreID ) == 0 ) \
{ \ { \
portCLEAR_INTERRUPT_MASK_FROM_ISR( xSavedInterruptStatus ); \ portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \
} \ } \
} while( 0 ) } while( 0 )
#endif /* #if ( portUSING_GRANULAR_LOCKS == 1 ) */ #endif /* #if ( portUSING_GRANULAR_LOCKS == 1 ) */

18
queue.c
View file

@ -260,13 +260,13 @@ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength,
* Macros to mark the start and end of a critical code region. * Macros to mark the start and end of a critical code region.
*/ */
#if ( portUSING_GRANULAR_LOCKS == 1 ) #if ( portUSING_GRANULAR_LOCKS == 1 )
#define queueENTER_CRITICAL( pxQueue ) taskDATA_GROUP_ENTER_CRITICAL( pxQueue ) #define queueENTER_CRITICAL( pxQueue ) taskDATA_GROUP_ENTER_CRITICAL( &pxQueue->xTaskSpinlock, &pxQueue->xISRSpinlock )
#define queueENTER_CRITICAL_FROM_ISR( pxQueue ) taskDATA_GROUP_ENTER_CRITICAL_FROM_ISR( pxQueue ) #define queueENTER_CRITICAL_FROM_ISR( pxQueue, puxSavedInterruptStatus ) taskDATA_GROUP_ENTER_CRITICAL_FROM_ISR( &pxQueue->xISRSpinlock, puxSavedInterruptStatus )
#define queueEXIT_CRITICAL( pxQueue ) taskDATA_GROUP_EXIT_CRITICAL( pxQueue ) #define queueEXIT_CRITICAL( pxQueue ) taskDATA_GROUP_EXIT_CRITICAL( &pxQueue->xTaskSpinlock, &pxQueue->xISRSpinlock )
#define queueEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus, pxQueue ) taskDATA_GROUP_EXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus, pxQueue ) #define queueEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus, pxQueue ) taskDATA_GROUP_EXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus, &pxQueue->xISRSpinlock )
#else /* #if ( portUSING_GRANULAR_LOCKS == 1 ) */ #else /* #if ( portUSING_GRANULAR_LOCKS == 1 ) */
#define queueENTER_CRITICAL( pxQueue ) taskENTER_CRITICAL(); #define queueENTER_CRITICAL( pxQueue ) taskENTER_CRITICAL();
#define queueENTER_CRITICAL_FROM_ISR( pxQueue ) taskENTER_CRITICAL_FROM_ISR(); #define queueENTER_CRITICAL_FROM_ISR( pxQueue, puxSavedInterruptStatus ) do { *( puxSavedInterruptStatus ) = taskENTER_CRITICAL_FROM_ISR(); } while( 0 )
#define queueEXIT_CRITICAL( pxQueue ) taskEXIT_CRITICAL(); #define queueEXIT_CRITICAL( pxQueue ) taskEXIT_CRITICAL();
#define queueEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus, pxQueue ) taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); #define queueEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus, pxQueue ) taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus );
#endif /* #if ( portUSING_GRANULAR_LOCKS == 1 ) */ #endif /* #if ( portUSING_GRANULAR_LOCKS == 1 ) */
@ -1266,7 +1266,7 @@ BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue,
/* MISRA Ref 4.7.1 [Return value shall be checked] */ /* MISRA Ref 4.7.1 [Return value shall be checked] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */
/* coverity[misra_c_2012_directive_4_7_violation] */ /* coverity[misra_c_2012_directive_4_7_violation] */
uxSavedInterruptStatus = ( UBaseType_t ) queueENTER_CRITICAL_FROM_ISR( pxQueue ); queueENTER_CRITICAL_FROM_ISR( pxQueue, &uxSavedInterruptStatus );
{ {
if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) ) if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) )
{ {
@ -1444,7 +1444,7 @@ BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue,
/* MISRA Ref 4.7.1 [Return value shall be checked] */ /* MISRA Ref 4.7.1 [Return value shall be checked] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */
/* coverity[misra_c_2012_directive_4_7_violation] */ /* coverity[misra_c_2012_directive_4_7_violation] */
uxSavedInterruptStatus = ( UBaseType_t ) queueENTER_CRITICAL_FROM_ISR( pxQueue ); queueENTER_CRITICAL_FROM_ISR( pxQueue, &uxSavedInterruptStatus );
{ {
const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting;
@ -2097,7 +2097,7 @@ BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue,
/* MISRA Ref 4.7.1 [Return value shall be checked] */ /* MISRA Ref 4.7.1 [Return value shall be checked] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */
/* coverity[misra_c_2012_directive_4_7_violation] */ /* coverity[misra_c_2012_directive_4_7_violation] */
uxSavedInterruptStatus = ( UBaseType_t ) queueENTER_CRITICAL_FROM_ISR( pxQueue ); queueENTER_CRITICAL_FROM_ISR( pxQueue, &uxSavedInterruptStatus );
{ {
const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting;
@ -2198,7 +2198,7 @@ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue,
/* MISRA Ref 4.7.1 [Return value shall be checked] */ /* MISRA Ref 4.7.1 [Return value shall be checked] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */
/* coverity[misra_c_2012_directive_4_7_violation] */ /* coverity[misra_c_2012_directive_4_7_violation] */
uxSavedInterruptStatus = ( UBaseType_t ) queueENTER_CRITICAL_FROM_ISR( pxQueue ); queueENTER_CRITICAL_FROM_ISR( pxQueue, &uxSavedInterruptStatus );
{ {
/* Cannot block in an ISR, so check there is data available. */ /* Cannot block in an ISR, so check there is data available. */
if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 )

View file

@ -63,14 +63,14 @@
* Macros to mark the start and end of a critical code region. * Macros to mark the start and end of a critical code region.
*/ */
#if ( portUSING_GRANULAR_LOCKS == 1 ) #if ( portUSING_GRANULAR_LOCKS == 1 )
#define sbENTER_CRITICAL( pxStreamBuffer ) taskDATA_GROUP_ENTER_CRITICAL( pxStreamBuffer ) #define sbENTER_CRITICAL( pxStreamBuffer ) taskDATA_GROUP_ENTER_CRITICAL( &pxStreamBuffer->xTaskSpinlock, &pxStreamBuffer->xISRSpinlock )
#define sbENTER_CRITICAL_FROM_ISR( pxStreamBuffer ) taskDATA_GROUP_ENTER_CRITICAL_FROM_ISR( pxStreamBuffer ) #define sbENTER_CRITICAL_FROM_ISR( pxStreamBuffer, puxSavedInterruptStatus ) taskDATA_GROUP_ENTER_CRITICAL_FROM_ISR( &pxStreamBuffer->xISRSpinlock, puxSavedInterruptStatus )
#define sbEXIT_CRITICAL( pxStreamBuffer ) taskDATA_GROUP_EXIT_CRITICAL( pxStreamBuffer ) #define sbEXIT_CRITICAL( pxStreamBuffer ) taskDATA_GROUP_EXIT_CRITICAL( &pxStreamBuffer->xTaskSpinlock, &pxStreamBuffer->xISRSpinlock )
#define sbEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus, pxStreamBuffer ) taskDATA_GROUP_EXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus, pxStreamBuffer ) #define sbEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus, pxStreamBuffer ) taskDATA_GROUP_EXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus, &pxStreamBuffer->xISRSpinlock )
#else /* #if ( portUSING_GRANULAR_LOCKS == 1 ) */ #else /* #if ( portUSING_GRANULAR_LOCKS == 1 ) */
#define sbENTER_CRITICAL( pxEventBits ) taskENTER_CRITICAL(); #define sbENTER_CRITICAL( pxStreamBuffer ) taskENTER_CRITICAL();
#define sbENTER_CRITICAL_FROM_ISR( pxEventBits ) taskENTER_CRITICAL_FROM_ISR(); #define sbENTER_CRITICAL_FROM_ISR( pxStreamBuffer, puxSavedInterruptStatus ) do { *( puxSavedInterruptStatus ) = taskENTER_CRITICAL_FROM_ISR(); } while( 0 )
#define sbEXIT_CRITICAL( pxEventBits ) taskEXIT_CRITICAL(); #define sbEXIT_CRITICAL( pxStreamBuffer ) taskEXIT_CRITICAL();
#define sbEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus, pxStreamBuffer ) taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); #define sbEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus, pxStreamBuffer ) taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus );
#endif /* #if ( portUSING_GRANULAR_LOCKS == 1 ) */ #endif /* #if ( portUSING_GRANULAR_LOCKS == 1 ) */
@ -138,7 +138,7 @@
do { \ do { \
UBaseType_t uxSavedInterruptStatus; \ UBaseType_t uxSavedInterruptStatus; \
\ \
uxSavedInterruptStatus = sbENTER_CRITICAL_FROM_ISR( pxStreamBuffer ); \ sbENTER_CRITICAL_FROM_ISR( pxStreamBuffer, &uxSavedInterruptStatus ); \
{ \ { \
if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \ if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \
{ \ { \
@ -217,7 +217,7 @@
do { \ do { \
UBaseType_t uxSavedInterruptStatus; \ UBaseType_t uxSavedInterruptStatus; \
\ \
uxSavedInterruptStatus = sbENTER_CRITICAL_FROM_ISR( pxStreamBuffer ); \ sbENTER_CRITICAL_FROM_ISR( pxStreamBuffer, &uxSavedInterruptStatus ); \
{ \ { \
if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \ if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \
{ \ { \
@ -1504,7 +1504,7 @@ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer
/* MISRA Ref 4.7.1 [Return value shall be checked] */ /* MISRA Ref 4.7.1 [Return value shall be checked] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */
/* coverity[misra_c_2012_directive_4_7_violation] */ /* coverity[misra_c_2012_directive_4_7_violation] */
uxSavedInterruptStatus = sbENTER_CRITICAL_FROM_ISR( pxStreamBuffer ); sbENTER_CRITICAL_FROM_ISR( pxStreamBuffer, &uxSavedInterruptStatus );
{ {
if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL )
{ {
@ -1543,7 +1543,7 @@ BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuf
/* MISRA Ref 4.7.1 [Return value shall be checked] */ /* MISRA Ref 4.7.1 [Return value shall be checked] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */
/* coverity[misra_c_2012_directive_4_7_violation] */ /* coverity[misra_c_2012_directive_4_7_violation] */
uxSavedInterruptStatus = sbENTER_CRITICAL_FROM_ISR( pxStreamBuffer ); sbENTER_CRITICAL_FROM_ISR( pxStreamBuffer, &uxSavedInterruptStatus );
{ {
if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL )
{ {

View file

@ -83,8 +83,8 @@
* Macros to mark the start and end of a critical code region. * Macros to mark the start and end of a critical code region.
*/ */
#if ( portUSING_GRANULAR_LOCKS == 1 ) #if ( portUSING_GRANULAR_LOCKS == 1 )
#define tmrENTER_CRITICAL() taskDATA_GROUP_ENTER_CRITICAL( &xTimerDataGroupLocks ) #define tmrENTER_CRITICAL() taskDATA_GROUP_ENTER_CRITICAL( &xTaskSpinlock, &xISRSpinlock )
#define tmrEXIT_CRITICAL() taskDATA_GROUP_EXIT_CRITICAL( &xTimerDataGroupLocks ) #define tmrEXIT_CRITICAL() taskDATA_GROUP_EXIT_CRITICAL( &xTaskSpinlock, &xISRSpinlock )
#else /* #if ( portUSING_GRANULAR_LOCKS == 1 ) */ #else /* #if ( portUSING_GRANULAR_LOCKS == 1 ) */
#define tmrENTER_CRITICAL() taskENTER_CRITICAL() #define tmrENTER_CRITICAL() taskENTER_CRITICAL()
#define tmrEXIT_CRITICAL() taskEXIT_CRITICAL() #define tmrEXIT_CRITICAL() taskEXIT_CRITICAL()
@ -161,16 +161,8 @@
PRIVILEGED_DATA static TaskHandle_t xTimerTaskHandle = NULL; PRIVILEGED_DATA static TaskHandle_t xTimerTaskHandle = NULL;
#if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) )
PRIVILEGED_DATA static struct PRIVILEGED_DATA static portSPINLOCK_TYPE xTaskSpinlock = portINIT_SPINLOCK_STATIC;
{ PRIVILEGED_DATA static portSPINLOCK_TYPE xISRSpinlock = portINIT_SPINLOCK_STATIC;
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 ) ) */ #endif /* #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/