Skip to content

Commit ca063bc

Browse files
Dazza0sudeep-mohanty
authored andcommitted
refactor(freertos/smp): Move critical section into vTaskPriorityDisinheritAfterTimeout()
Previously, xQueueSemaphoreTake() would need to enter a critical section then call prvGetDisinheritPriorityAfterTimeout() and vTaskPriorityDisinheritAfterTimeout() separately. This commit refactors vTaskPriorityDisinheritAfterTimeout where: - The fucnction now checks the highest priority waiting task of the mutex - Moves the critical section into the function
1 parent ceffe51 commit ca063bc

File tree

4 files changed

+88
-67
lines changed

4 files changed

+88
-67
lines changed

include/FreeRTOS.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2233,7 +2233,7 @@
22332233
#endif
22342234

22352235
#ifndef traceENTER_vTaskPriorityDisinheritAfterTimeout
2236-
#define traceENTER_vTaskPriorityDisinheritAfterTimeout( pxMutexHolder, uxHighestPriorityWaitingTask )
2236+
#define traceENTER_vTaskPriorityDisinheritAfterTimeout( pxMutexHolder, pxEventList )
22372237
#endif
22382238

22392239
#ifndef traceRETURN_vTaskPriorityDisinheritAfterTimeout

include/task.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3627,7 +3627,7 @@ BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder ) PRIVILEGE
36273627
* more than one task waiting for the mutex).
36283628
*/
36293629
void vTaskPriorityDisinheritAfterTimeout( TaskHandle_t const pxMutexHolder,
3630-
UBaseType_t uxHighestPriorityWaitingTask ) PRIVILEGED_FUNCTION;
3630+
List_t * pxEventList ) PRIVILEGED_FUNCTION;
36313631

36323632
/*
36333633
* Get the uxTaskNumber assigned to the task referenced by the xTask parameter.

queue.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2356,6 +2356,7 @@ UBaseType_t uxQueueGetQueueLength( QueueHandle_t xQueue ) /* PRIVILEGED_FUNCTION
23562356
}
23572357
/*-----------------------------------------------------------*/
23582358

2359+
<<<<<<< HEAD
23592360
#if ( configUSE_MUTEXES == 1 )
23602361

23612362
static UBaseType_t prvGetHighestPriorityOfWaitToReceiveList( const Queue_t * const pxQueue )
@@ -2383,6 +2384,8 @@ UBaseType_t uxQueueGetQueueLength( QueueHandle_t xQueue ) /* PRIVILEGED_FUNCTION
23832384
#endif /* configUSE_MUTEXES */
23842385
/*-----------------------------------------------------------*/
23852386

2387+
=======
2388+
>>>>>>> 0c3343dd2 (refactor(freertos/smp): Move critical section into vTaskPriorityDisinheritAfterTimeout())
23862389
static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue,
23872390
const void * pvItemToQueue,
23882391
const BaseType_t xPosition )

tasks.c

Lines changed: 83 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -6791,96 +6791,117 @@ static void prvResetNextTaskUnblockTime( void )
67916791
#if ( configUSE_MUTEXES == 1 )
67926792

67936793
void vTaskPriorityDisinheritAfterTimeout( TaskHandle_t const pxMutexHolder,
6794-
UBaseType_t uxHighestPriorityWaitingTask )
6794+
List_t * pxEventList )
67956795
{
6796+
UBaseType_t uxHighestPriorityWaitingTask;
67966797
TCB_t * const pxTCB = pxMutexHolder;
67976798
UBaseType_t uxPriorityUsedOnEntry, uxPriorityToUse;
67986799
const UBaseType_t uxOnlyOneMutexHeld = ( UBaseType_t ) 1;
67996800

6800-
traceENTER_vTaskPriorityDisinheritAfterTimeout( pxMutexHolder, uxHighestPriorityWaitingTask );
6801+
traceENTER_vTaskPriorityDisinheritAfterTimeout( pxMutexHolder, pxEventList );
68016802

6802-
if( pxMutexHolder != NULL )
6803+
taskENTER_CRITICAL();
68036804
{
6804-
/* If pxMutexHolder is not NULL then the holder must hold at least
6805-
* one mutex. */
6806-
configASSERT( pxTCB->uxMutexesHeld );
6807-
6808-
/* Determine the priority to which the priority of the task that
6809-
* holds the mutex should be set. This will be the greater of the
6810-
* holding task's base priority and the priority of the highest
6811-
* priority task that is waiting to obtain the mutex. */
6812-
if( pxTCB->uxBasePriority < uxHighestPriorityWaitingTask )
6805+
/* If a task waiting for a mutex causes the mutex holder to inherit a
6806+
* priority, but the waiting task times out, then the holder should
6807+
* disinherit the priority - but only down to the highest priority of any
6808+
* other tasks that are waiting for the same mutex. */
6809+
if( listCURRENT_LIST_LENGTH( pxEventList ) > 0U )
68136810
{
6814-
uxPriorityToUse = uxHighestPriorityWaitingTask;
6811+
uxHighestPriorityWaitingTask = ( UBaseType_t ) ( ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxEventList ) );
68156812
}
68166813
else
68176814
{
6818-
uxPriorityToUse = pxTCB->uxBasePriority;
6815+
uxHighestPriorityWaitingTask = tskIDLE_PRIORITY;
68196816
}
68206817

6821-
/* Does the priority need to change? */
6822-
if( pxTCB->uxPriority != uxPriorityToUse )
6818+
if( pxMutexHolder != NULL )
68236819
{
6824-
/* Only disinherit if no other mutexes are held. This is a
6825-
* simplification in the priority inheritance implementation. If
6826-
* the task that holds the mutex is also holding other mutexes then
6827-
* the other mutexes may have caused the priority inheritance. */
6828-
if( pxTCB->uxMutexesHeld == uxOnlyOneMutexHeld )
6829-
{
6830-
/* If a task has timed out because it already holds the
6831-
* mutex it was trying to obtain then it cannot of inherited
6832-
* its own priority. */
6833-
configASSERT( pxTCB != pxCurrentTCB );
6820+
/* If pxMutexHolder is not NULL then the holder must hold at least
6821+
* one mutex. */
6822+
configASSERT( pxTCB->uxMutexesHeld );
68346823

6835-
/* Disinherit the priority, remembering the previous
6836-
* priority to facilitate determining the subject task's
6837-
* state. */
6838-
traceTASK_PRIORITY_DISINHERIT( pxTCB, uxPriorityToUse );
6839-
uxPriorityUsedOnEntry = pxTCB->uxPriority;
6840-
pxTCB->uxPriority = uxPriorityToUse;
6824+
/* Determine the priority to which the priority of the task that
6825+
* holds the mutex should be set. This will be the greater of the
6826+
* holding task's base priority and the priority of the highest
6827+
* priority task that is waiting to obtain the mutex. */
6828+
if( pxTCB->uxBasePriority < uxHighestPriorityWaitingTask )
6829+
{
6830+
uxPriorityToUse = uxHighestPriorityWaitingTask;
6831+
}
6832+
else
6833+
{
6834+
uxPriorityToUse = pxTCB->uxBasePriority;
6835+
}
68416836

6842-
/* Only reset the event list item value if the value is not
6843-
* being used for anything else. */
6844-
if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == ( ( TickType_t ) 0U ) )
6845-
{
6846-
listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxPriorityToUse );
6847-
}
6848-
else
6837+
/* Does the priority need to change? */
6838+
if( pxTCB->uxPriority != uxPriorityToUse )
6839+
{
6840+
/* Only disinherit if no other mutexes are held. This is a
6841+
* simplification in the priority inheritance implementation. If
6842+
* the task that holds the mutex is also holding other mutexes then
6843+
* the other mutexes may have caused the priority inheritance. */
6844+
if( pxTCB->uxMutexesHeld == uxOnlyOneMutexHeld )
68496845
{
6850-
mtCOVERAGE_TEST_MARKER();
6851-
}
6846+
/* If a task has timed out because it already holds the
6847+
* mutex it was trying to obtain then it cannot of inherited
6848+
* its own priority. */
6849+
configASSERT( pxTCB != pxCurrentTCB );
68526850

6853-
/* If the running task is not the task that holds the mutex
6854-
* then the task that holds the mutex could be in either the
6855-
* Ready, Blocked or Suspended states. Only remove the task
6856-
* from its current state list if it is in the Ready state as
6857-
* the task's priority is going to change and there is one
6858-
* Ready list per priority. */
6859-
if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxPriorityUsedOnEntry ] ), &( pxTCB->xStateListItem ) ) != pdFALSE )
6860-
{
6861-
if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 )
6851+
/* Disinherit the priority, remembering the previous
6852+
* priority to facilitate determining the subject task's
6853+
* state. */
6854+
traceTASK_PRIORITY_DISINHERIT( pxTCB, uxPriorityToUse );
6855+
uxPriorityUsedOnEntry = pxTCB->uxPriority;
6856+
pxTCB->uxPriority = uxPriorityToUse;
6857+
6858+
/* Only reset the event list item value if the value is not
6859+
* being used for anything else. */
6860+
if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == ( ( TickType_t ) 0U ) )
68626861
{
6863-
/* It is known that the task is in its ready list so
6864-
* there is no need to check again and the port level
6865-
* reset macro can be called directly. */
6866-
portRESET_READY_PRIORITY( pxTCB->uxPriority, uxTopReadyPriority );
6862+
listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxPriorityToUse );
68676863
}
68686864
else
68696865
{
68706866
mtCOVERAGE_TEST_MARKER();
68716867
}
68726868

6873-
prvAddTaskToReadyList( pxTCB );
6874-
#if ( configNUMBER_OF_CORES > 1 )
6869+
/* If the running task is not the task that holds the mutex
6870+
* then the task that holds the mutex could be in either the
6871+
* Ready, Blocked or Suspended states. Only remove the task
6872+
* from its current state list if it is in the Ready state as
6873+
* the task's priority is going to change and there is one
6874+
* Ready list per priority. */
6875+
if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxPriorityUsedOnEntry ] ), &( pxTCB->xStateListItem ) ) != pdFALSE )
68756876
{
6876-
/* The priority of the task is dropped. Yield the core on
6877-
* which the task is running. */
6878-
if( taskTASK_IS_RUNNING( pxTCB ) == pdTRUE )
6877+
if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 )
6878+
{
6879+
/* It is known that the task is in its ready list so
6880+
* there is no need to check again and the port level
6881+
* reset macro can be called directly. */
6882+
portRESET_READY_PRIORITY( pxTCB->uxPriority, uxTopReadyPriority );
6883+
}
6884+
else
68796885
{
6880-
prvYieldCore( pxTCB->xTaskRunState );
6886+
mtCOVERAGE_TEST_MARKER();
6887+
}
6888+
6889+
prvAddTaskToReadyList( pxTCB );
6890+
#if ( configNUMBER_OF_CORES > 1 )
6891+
{
6892+
/* The priority of the task is dropped. Yield the core on
6893+
* which the task is running. */
6894+
if( taskTASK_IS_RUNNING( pxTCB ) == pdTRUE )
6895+
{
6896+
prvYieldCore( pxTCB->xTaskRunState );
6897+
}
68816898
}
6899+
#endif /* if ( configNUMBER_OF_CORES > 1 ) */
6900+
}
6901+
else
6902+
{
6903+
mtCOVERAGE_TEST_MARKER();
68826904
}
6883-
#endif /* if ( configNUMBER_OF_CORES > 1 ) */
68846905
}
68856906
else
68866907
{
@@ -6897,10 +6918,7 @@ static void prvResetNextTaskUnblockTime( void )
68976918
mtCOVERAGE_TEST_MARKER();
68986919
}
68996920
}
6900-
else
6901-
{
6902-
mtCOVERAGE_TEST_MARKER();
6903-
}
6921+
taskEXIT_CRITICAL();
69046922

69056923
traceRETURN_vTaskPriorityDisinheritAfterTimeout();
69066924
}

0 commit comments

Comments
 (0)