mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2026-01-21 17:20:32 -05:00
fix(freertos-smp): Miscellaneous fixes for granular locks
This commit is contained in:
parent
e3d92dd5fd
commit
35025858cf
7 changed files with 302 additions and 359 deletions
|
|
@ -87,24 +87,6 @@
|
|||
#define event_groupsEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus, pxEventBits ) taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus );
|
||||
#endif /* #if ( portUSING_GRANULAR_LOCKS == 1 ) */
|
||||
|
||||
/*
|
||||
* Locks an event group for tasks. Prevents other tasks from accessing the event group but allows
|
||||
* ISRs to pend access to the event group. Caller cannot be preempted by other tasks
|
||||
* after locking the event group, thus allowing the caller to execute non-deterministic
|
||||
* operations.
|
||||
*/
|
||||
#if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) )
|
||||
static void prvLockEventGroupForTasks( EventGroup_t * pxEventBits ) PRIVILEGED_FUNCTION;
|
||||
#endif /* #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) */
|
||||
|
||||
/*
|
||||
* Unlocks an event group for tasks. Handles all pended access from ISRs, then reenables
|
||||
* preemption for the caller.
|
||||
*/
|
||||
#if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) )
|
||||
static BaseType_t prvUnlockEventGroupForTasks( EventGroup_t * pxEventBits ) PRIVILEGED_FUNCTION;
|
||||
#endif /* #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) */
|
||||
|
||||
/*
|
||||
* Test the bits set in uxCurrentEventBits to see if the wait condition is met.
|
||||
* The wait condition is defined by xWaitForAllBits. If xWaitForAllBits is
|
||||
|
|
@ -129,8 +111,22 @@
|
|||
* When the task unlocks the event group, all pended access attempts are handled.
|
||||
*/
|
||||
#if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) )
|
||||
#define event_groupsLOCK( pxEventBits ) prvLockEventGroupForTasks( pxEventBits )
|
||||
#define event_groupsUNLOCK( pxEventBits ) prvUnlockEventGroupForTasks( pxEventBits );
|
||||
#define event_groupsLOCK( pxEventBits ) taskDATA_GROUP_LOCK( &( ( pxEventBits )->xTaskSpinlock ) )
|
||||
#define event_groupsUNLOCK( pxEventBits ) \
|
||||
( { \
|
||||
taskDATA_GROUP_UNLOCK( &( ( pxEventBits )->xTaskSpinlock ) ); \
|
||||
BaseType_t xAlreadyYielded; \
|
||||
if( xTaskUnlockCanYield() == pdTRUE ) \
|
||||
{ \
|
||||
taskYIELD_WITHIN_API(); \
|
||||
xAlreadyYielded = pdTRUE; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
xAlreadyYielded = pdFALSE; \
|
||||
} \
|
||||
xAlreadyYielded; \
|
||||
} )
|
||||
#else /* #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) */
|
||||
#define event_groupsLOCK( pxEventBits ) vTaskSuspendAll()
|
||||
#define event_groupsUNLOCK( pxEventBits ) xTaskResumeAll()
|
||||
|
|
@ -867,48 +863,6 @@
|
|||
traceRETURN_vEventGroupClearBitsCallback();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
#if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) )
|
||||
static void prvLockEventGroupForTasks( EventGroup_t * pxEventBits )
|
||||
{
|
||||
/* Disable preemption so that the current task cannot be preempted by another task */
|
||||
vTaskPreemptionDisable( NULL );
|
||||
|
||||
/* Keep holding xTaskSpinlock to prevent tasks on other cores from accessing
|
||||
* the event group while it is suspended. */
|
||||
portGET_SPINLOCK( portGET_CORE_ID(), &( pxEventBits->xTaskSpinlock ) );
|
||||
}
|
||||
#endif /* #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) )
|
||||
static BaseType_t prvUnlockEventGroupForTasks( EventGroup_t * pxEventBits )
|
||||
{
|
||||
BaseType_t xReturn = pdFALSE;
|
||||
|
||||
/* Release the previously held task spinlock */
|
||||
portRELEASE_SPINLOCK( portGET_CORE_ID(), &( pxEventBits->xTaskSpinlock ) );
|
||||
|
||||
/* Re-enable preemption */
|
||||
vTaskPreemptionEnable( NULL );
|
||||
|
||||
/* Yield if preemption was re-enabled*/
|
||||
if( xTaskUnlockCanYield() == pdTRUE )
|
||||
{
|
||||
taskYIELD_WITHIN_API();
|
||||
|
||||
/* Return true as the task was preempted */
|
||||
xReturn = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Return false as the task was not preempted */
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
#endif /* #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue