From d4b8bfdb36676a302a6445a7822afda65c13c051 Mon Sep 17 00:00:00 2001 From: "Ching-Hsin,Lee" Date: Mon, 20 May 2024 12:36:28 +0800 Subject: [PATCH] First version of pxCurrentTCB --- tasks.c | 303 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 167 insertions(+), 136 deletions(-) diff --git a/tasks.c b/tasks.c index 3423becd4..633b3cf56 100644 --- a/tasks.c +++ b/tasks.c @@ -84,16 +84,17 @@ portYIELD_WITHIN_API(); \ } while( 0 ) - #define taskYIELD_ANY_CORE_IF_USING_PREEMPTION( pxTCB ) \ - do { \ - if( pxCurrentTCB->uxPriority < ( pxTCB )->uxPriority ) \ - { \ - portYIELD_WITHIN_API(); \ - } \ - else \ - { \ - mtCOVERAGE_TEST_MARKER(); \ - } \ + #define taskYIELD_ANY_CORE_IF_USING_PREEMPTION( pxTCB ) \ + do { \ + TCB_t * const pxConstCurrentTCB = prvGetCurrentTask(); \ + if( pxConstCurrentTCB->uxPriority < ( pxTCB )->uxPriority ) \ + { \ + portYIELD_WITHIN_API(); \ + } \ + else \ + { \ + mtCOVERAGE_TEST_MARKER(); \ + } \ } while( 0 ) #else /* if ( configNUMBER_OF_CORES == 1 ) */ @@ -216,14 +217,15 @@ /*-----------------------------------------------------------*/ - #define taskSELECT_HIGHEST_PRIORITY_TASK() \ - do { \ - UBaseType_t uxTopPriority; \ - \ - /* Find the highest priority list that contains ready tasks. */ \ - portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority ); \ - configASSERT( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ uxTopPriority ] ) ) > 0 ); \ - listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ + #define taskSELECT_HIGHEST_PRIORITY_TASK() \ + do { \ + UBaseType_t uxTopPriority; \ + TCB_t * const pxConstCurrentTCB = prvGetCurrentTask(); \ + \ + /* Find the highest priority list that contains ready tasks. */ \ + portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority ); \ + configASSERT( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ uxTopPriority ] ) ) > 0 ); \ + listGET_OWNER_OF_NEXT_ENTRY( pxConstCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ } while( 0 ) /*-----------------------------------------------------------*/ @@ -280,7 +282,7 @@ * task should be used in place of the parameter. This macro simply checks to * see if the parameter is NULL and returns a pointer to the appropriate TCB. */ -#define prvGetTCBFromHandle( pxHandle ) ( ( ( pxHandle ) == NULL ) ? pxCurrentTCB : ( pxHandle ) ) +#define prvGetTCBFromHandle( pxHandle ) ( ( ( pxHandle ) == NULL ) ? prvGetCurrentTask() : ( pxHandle ) ) /* The item value of the event list item is normally used to hold the priority * of the task to which it belongs (coded to allow it to be held in reverse @@ -439,6 +441,13 @@ typedef struct tskTaskControlBlock /* The old naming convention is used to * below to enable the use of older kernel aware debuggers. */ typedef tskTCB TCB_t; +#if configNUMBER_OF_CORES == 1 + #define prvGetCurrentTaskImmutable() pxCurrentTCB + #define prvGetCurrentTask() pxCurrentTCB +#else + #define prvGetCurrentTaskImmutable() pxCurrentTCBs[ portGET_CORE_ID() ] +#endif + #if ( configNUMBER_OF_CORES == 1 ) /* MISRA Ref 8.4.1 [Declaration shall be visible] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ @@ -449,7 +458,6 @@ typedef tskTCB TCB_t; /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-84 */ /* coverity[misra_c_2012_rule_8_4_violation] */ portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCBs[ configNUMBER_OF_CORES ]; - #define pxCurrentTCB xTaskGetCurrentTaskHandle() #endif /* Lists for ready and blocked tasks. -------------------- @@ -801,6 +809,23 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; #endif /* #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) */ /*-----------------------------------------------------------*/ +#if ( configNUMBER_OF_CORES > 1 ) + + static TCB_t * prvGetCurrentTask( void ) + { + TCB_t * pxTCB; + UBaseType_t uxSavedInterruptStatus; + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK(); + { + pxTCB = pxCurrentTCBs[ portGET_CORE_ID() ]; + } + portCLEAR_INTERRUPT_MASK( uxSavedInterruptStatus ); + + return pxTCB; + } +#endif /* if ( configNUMBER_OF_CORES > 1 ) */ + #if ( configNUMBER_OF_CORES > 1 ) static void prvCheckForRunStateChange( void ) { @@ -2278,7 +2303,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, * ready list. */ #if ( configNUMBER_OF_CORES > 1 ) { - if( taskTASK_IS_RUNNING( pxTCB ) == pdTRUE ) + if( taskTASK_IS_RUNNING( pxTCB ) != pdFALSE ) { if( pxTCB->xTaskRunState == ( BaseType_t ) portGET_CORE_ID() ) { @@ -2319,7 +2344,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, { if( xSchedulerRunning != pdFALSE ) { - if( pxTCB == pxCurrentTCB ) + if( taskTASK_IS_RUNNING( pxTCB ) != pdFALSE ) { configASSERT( uxSchedulerSuspended == 0 ); taskYIELD_WITHIN_API(); @@ -2496,7 +2521,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, configASSERT( pxTCB ); #if ( configNUMBER_OF_CORES == 1 ) - if( pxTCB == pxCurrentTCB ) + if( taskTASK_IS_RUNNING( pxTCB ) == pdTRUE ) { /* The task calling this function is querying its own state. */ eReturn = eRunning; @@ -2768,6 +2793,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, TCB_t * pxTCB; UBaseType_t uxCurrentBasePriority, uxPriorityUsedOnEntry; BaseType_t xYieldRequired = pdFALSE; + TCB_t * const pxConstCurrentTCB = prvGetCurrentTask(); #if ( configNUMBER_OF_CORES > 1 ) BaseType_t xYieldForTask = pdFALSE; @@ -2813,12 +2839,12 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, { #if ( configNUMBER_OF_CORES == 1 ) { - if( pxTCB != pxCurrentTCB ) + if( taskTASK_IS_RUNNING( pxTCB ) != pdTRUE ) { /* The priority of a task other than the currently * running task is being raised. Is the priority being * raised above that of the running task? */ - if( uxNewPriority > pxCurrentTCB->uxPriority ) + if( uxNewPriority > pxConstCurrentTCB->uxPriority ) { xYieldRequired = pdTRUE; } @@ -3232,7 +3258,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, mtCOVERAGE_TEST_MARKER(); } - if( pxTCB == pxCurrentTCB ) + if( taskTASK_IS_RUNNING( pxTCB ) != pdFALSE ) { if( xSchedulerRunning != pdFALSE ) { @@ -3363,7 +3389,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, /* The parameter cannot be NULL as it is impossible to resume the * currently executing task. */ - if( ( pxTCB != pxCurrentTCB ) && ( pxTCB != NULL ) ) + if( ( taskTASK_IS_RUNNING( pxTCB ) != pdTRUE ) && ( pxTCB != NULL ) ) #else /* The parameter cannot be NULL as it is impossible to resume the @@ -3416,6 +3442,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, BaseType_t xYieldRequired = pdFALSE; TCB_t * const pxTCB = xTaskToResume; UBaseType_t uxSavedInterruptStatus; + TCB_t * const pxConstCurrentTCB = prvGetCurrentTaskImmutable(); traceENTER_xTaskResumeFromISR( xTaskToResume ); @@ -3455,7 +3482,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, { /* Ready lists can be accessed so move the task from the * suspended list to the ready list directly. */ - if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + if( pxTCB->uxPriority > pxConstCurrentTCB->uxPriority ) { xYieldRequired = pdTRUE; @@ -3711,9 +3738,11 @@ void vTaskStartScheduler( void ) #if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) { + TCB_t * const pxConstCurrentTCB = prvGetCurrentTask(); + /* Switch C-Runtime's TLS Block to point to the TLS * block specific to the task that will run first. */ - configSET_TLS_BLOCK( pxCurrentTCB->xTLSBlock ); + configSET_TLS_BLOCK( pxConstCurrentTCB->xTLSBlock ); } #endif @@ -3895,6 +3924,7 @@ void vTaskSuspendAll( void ) { TickType_t xReturn; UBaseType_t uxHigherPriorityReadyTasks = pdFALSE; + TCB_t * const pxConstCurrentTCB = prvGetCurrentTask(); /* uxHigherPriorityReadyTasks takes care of the case where * configUSE_PREEMPTION is 0, so there may be tasks above the idle priority @@ -3923,7 +3953,7 @@ void vTaskSuspendAll( void ) } #endif /* if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 ) */ - if( pxCurrentTCB->uxPriority > tskIDLE_PRIORITY ) + if( pxConstCurrentTCB->uxPriority > tskIDLE_PRIORITY ) { xReturn = 0; } @@ -3972,6 +4002,8 @@ BaseType_t xTaskResumeAll( void ) taskENTER_CRITICAL(); { BaseType_t xCoreID; + TCB_t * const pxConstCurrentTCB = prvGetCurrentTaskImmutable(); + xCoreID = ( BaseType_t ) portGET_CORE_ID(); /* If uxSchedulerSuspended is zero then this function does not match a @@ -4002,7 +4034,7 @@ BaseType_t xTaskResumeAll( void ) { /* If the moved task has a priority higher than the current * task then a yield must be performed. */ - if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + if( pxTCB->uxPriority > pxConstCurrentTCB->uxPriority ) { xYieldPendings[ xCoreID ] = pdTRUE; } @@ -4626,10 +4658,12 @@ BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) { #if ( configNUMBER_OF_CORES == 1 ) { + TCB_t * const pxCurrentTCB = prvGetCurrentTask(); + /* Preemption is on, but a context switch should only be * performed if the unblocked task has a priority that is * higher than the currently executing task. */ - if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + if( pxTCB->uxPriority > pxConstCurrentTCB->uxPriority ) { /* Pend the yield to be performed when the scheduler * is unsuspended. */ @@ -4672,6 +4706,7 @@ BaseType_t xTaskIncrementTick( void ) TCB_t * pxTCB; TickType_t xItemValue; BaseType_t xSwitchRequired = pdFALSE; + TCB_t * const pxConstCurrentTCB = prvGetCurrentTaskImmutable(); #if ( configUSE_PREEMPTION == 1 ) && ( configNUMBER_OF_CORES > 1 ) BaseType_t xYieldRequiredForCore[ configNUMBER_OF_CORES ] = { pdFALSE }; @@ -4784,7 +4819,7 @@ BaseType_t xTaskIncrementTick( void ) * processing time (which happens when both * preemption and time slicing are on) is * handled below.*/ - if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + if( pxTCB->uxPriority > pxConstCurrentTCB->uxPriority ) { xSwitchRequired = pdTRUE; } @@ -4811,7 +4846,7 @@ BaseType_t xTaskIncrementTick( void ) { #if ( configNUMBER_OF_CORES == 1 ) { - if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ pxCurrentTCB->uxPriority ] ) ) > 1U ) + if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ pxConstCurrentTCB->uxPriority ] ) ) > 1U ) { xSwitchRequired = pdTRUE; } @@ -4926,26 +4961,19 @@ BaseType_t xTaskIncrementTick( void ) void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) { - TCB_t * xTCB; + TCB_t * pxTCB; traceENTER_vTaskSetApplicationTaskTag( xTask, pxHookFunction ); /* If xTask is NULL then it is the task hook of the calling task that is * getting set. */ - if( xTask == NULL ) - { - xTCB = ( TCB_t * ) pxCurrentTCB; - } - else - { - xTCB = xTask; - } + pxTCB = prvGetTCBFromHandle( xTask ); /* Save the hook function in the TCB. A critical section is required as * the value can be accessed from an interrupt. */ taskENTER_CRITICAL(); { - xTCB->pxTaskTag = pxHookFunction; + pxTCB->pxTaskTag = pxHookFunction; } taskEXIT_CRITICAL(); @@ -5020,24 +5048,17 @@ BaseType_t xTaskIncrementTick( void ) BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void * pvParameter ) { - TCB_t * xTCB; + TCB_t * pxTCB; BaseType_t xReturn; traceENTER_xTaskCallApplicationTaskHook( xTask, pvParameter ); /* If xTask is NULL then we are calling our own task hook. */ - if( xTask == NULL ) - { - xTCB = pxCurrentTCB; - } - else - { - xTCB = xTask; - } + pxTCB = prvGetTCBFromHandle( xTask ); - if( xTCB->pxTaskTag != NULL ) + if( pxTCB->pxTaskTag != NULL ) { - xReturn = xTCB->pxTaskTag( pvParameter ); + xReturn = pxTCB->pxTaskTag( pvParameter ); } else { @@ -5214,7 +5235,7 @@ BaseType_t xTaskIncrementTick( void ) /* Macro to inject port specific behaviour immediately after * switching tasks, such as setting an end of stack watchpoint * or reconfiguring the MPU. */ - portTASK_SWITCH_HOOK( pxCurrentTCBs[ portGET_CORE_ID() ] ); + portTASK_SWITCH_HOOK( pxCurrentTCBs[ xCoreID ] ); /* After the new task is switched in, update the global errno. */ #if ( configUSE_POSIX_ERRNO == 1 ) @@ -5243,6 +5264,8 @@ BaseType_t xTaskIncrementTick( void ) void vTaskPlaceOnEventList( List_t * const pxEventList, const TickType_t xTicksToWait ) { + TCB_t * const pxConstCurrentTCB = prvGetCurrentTaskImmutable(); + traceENTER_vTaskPlaceOnEventList( pxEventList, xTicksToWait ); configASSERT( pxEventList ); @@ -5261,7 +5284,7 @@ void vTaskPlaceOnEventList( List_t * const pxEventList, * * The queue that contains the event list is locked, preventing * simultaneous access from interrupts. */ - vListInsert( pxEventList, &( pxCurrentTCB->xEventListItem ) ); + vListInsert( pxEventList, &( pxConstCurrentTCB->xEventListItem ) ); prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); @@ -5273,6 +5296,8 @@ void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, const TickType_t xItemValue, const TickType_t xTicksToWait ) { + TCB_t * const pxConstCurrentTCB = prvGetCurrentTaskImmutable(); + traceENTER_vTaskPlaceOnUnorderedEventList( pxEventList, xItemValue, xTicksToWait ); configASSERT( pxEventList ); @@ -5284,14 +5309,14 @@ void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, /* Store the item value in the event list item. It is safe to access the * event list item here as interrupts won't access the event list item of a * task that is not in the Blocked state. */ - listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ), xItemValue | taskEVENT_LIST_ITEM_VALUE_IN_USE ); + listSET_LIST_ITEM_VALUE( &( pxConstCurrentTCB->xEventListItem ), xItemValue | taskEVENT_LIST_ITEM_VALUE_IN_USE ); /* Place the event list item of the TCB at the end of the appropriate event * list. It is safe to access the event list here because it is part of an * event group implementation - and interrupts don't access event groups * directly (instead they access them indirectly by pending function calls to * the task level). */ - listINSERT_END( pxEventList, &( pxCurrentTCB->xEventListItem ) ); + listINSERT_END( pxEventList, &( pxConstCurrentTCB->xEventListItem ) ); prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); @@ -5305,6 +5330,8 @@ void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) { + TCB_t * const pxConstCurrentTCB = prvGetCurrentTaskImmutable(); + traceENTER_vTaskPlaceOnEventListRestricted( pxEventList, xTicksToWait, xWaitIndefinitely ); configASSERT( pxEventList ); @@ -5319,7 +5346,7 @@ void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, * In this case it is assume that this is the only task that is going to * be waiting on this event list, so the faster vListInsertEnd() function * can be used in place of vListInsert. */ - listINSERT_END( pxEventList, &( pxCurrentTCB->xEventListItem ) ); + listINSERT_END( pxEventList, &( pxConstCurrentTCB->xEventListItem ) ); /* If the task should block indefinitely then set the block time to a * value that will be recognised as an indefinite delay inside the @@ -5343,6 +5370,8 @@ BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) TCB_t * pxUnblockedTCB; BaseType_t xReturn; + TCB_t * const pxConstCurrentTCB = prvGetCurrentTaskImmutable(); + traceENTER_xTaskRemoveFromEventList( pxEventList ); /* THIS FUNCTION MUST BE CALLED FROM A CRITICAL SECTION. It can also be @@ -5393,7 +5422,7 @@ BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) #if ( configNUMBER_OF_CORES == 1 ) { - if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority ) + if( pxUnblockedTCB->uxPriority > pxConstCurrentTCB->uxPriority ) { /* Return true if the task removed from the event list has a higher * priority than the calling task. This allows the calling task to know if @@ -5435,6 +5464,7 @@ void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue ) { TCB_t * pxUnblockedTCB; + TCB_t * const pxConstCurrentTCB = prvGetCurrentTaskImmutable(); traceENTER_vTaskRemoveFromUnorderedEventList( pxEventListItem, xItemValue ); @@ -5476,7 +5506,7 @@ void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, #if ( configNUMBER_OF_CORES == 1 ) { - if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority ) + if( pxUnblockedTCB->uxPriority > pxConstCurrentTCB->uxPriority ) { /* The unblocked task has a priority above that of the calling task, so * a context switch is required. This function is called with the @@ -5536,6 +5566,10 @@ BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, { BaseType_t xReturn; + #if ( INCLUDE_xTaskAbortDelay == 1 ) + TCB_t * const pxConstCurrentTCB = prvGetCurrentTaskImmutable(); + #endif + traceENTER_xTaskCheckForTimeOut( pxTimeOut, pxTicksToWait ); configASSERT( pxTimeOut ); @@ -5548,11 +5582,11 @@ BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, const TickType_t xElapsedTime = xConstTickCount - pxTimeOut->xTimeOnEntering; #if ( INCLUDE_xTaskAbortDelay == 1 ) - if( pxCurrentTCB->ucDelayAborted != ( uint8_t ) pdFALSE ) + if( pxConstCurrentTCB->ucDelayAborted != ( uint8_t ) pdFALSE ) { /* The delay was aborted, which is not the same as a time out, * but has the same result. */ - pxCurrentTCB->ucDelayAborted = ( uint8_t ) pdFALSE; + pxConstCurrentTCB->ucDelayAborted = ( uint8_t ) pdFALSE; xReturn = pdTRUE; } else @@ -6476,41 +6510,24 @@ static void prvResetNextTaskUnblockTime( void ) #if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) || ( configNUMBER_OF_CORES > 1 ) - #if ( configNUMBER_OF_CORES == 1 ) - TaskHandle_t xTaskGetCurrentTaskHandle( void ) - { - TaskHandle_t xReturn; + TaskHandle_t xTaskGetCurrentTaskHandle( void ) + { + TaskHandle_t xReturn; - traceENTER_xTaskGetCurrentTaskHandle(); + traceENTER_xTaskGetCurrentTaskHandle(); - /* A critical section is not required as this is not called from - * an interrupt and the current TCB will always be the same for any - * individual execution thread. */ - xReturn = pxCurrentTCB; + /* A critical section is not required as this is not called from + * an interrupt and the current TCB will always be the same for any + * individual execution thread. */ - traceRETURN_xTaskGetCurrentTaskHandle( xReturn ); + /* In SMP environment, interrupt must be disabled to get the current + * task TCB. */ + xReturn = prvGetCurrentTask(); - return xReturn; - } - #else /* #if ( configNUMBER_OF_CORES == 1 ) */ - TaskHandle_t xTaskGetCurrentTaskHandle( void ) - { - TaskHandle_t xReturn; - UBaseType_t uxSavedInterruptStatus; + traceRETURN_xTaskGetCurrentTaskHandle( xReturn ); - traceENTER_xTaskGetCurrentTaskHandle(); - - uxSavedInterruptStatus = portSET_INTERRUPT_MASK(); - { - xReturn = pxCurrentTCBs[ portGET_CORE_ID() ]; - } - portCLEAR_INTERRUPT_MASK( uxSavedInterruptStatus ); - - traceRETURN_xTaskGetCurrentTaskHandle( xReturn ); - - return xReturn; - } - #endif /* #if ( configNUMBER_OF_CORES == 1 ) */ + return xReturn; + } TaskHandle_t xTaskGetCurrentTaskHandleForCore( BaseType_t xCoreID ) { @@ -6582,6 +6599,8 @@ static void prvResetNextTaskUnblockTime( void ) TCB_t * const pxMutexHolderTCB = pxMutexHolder; BaseType_t xReturn = pdFALSE; + TCB_t * const pxConstCurrentTCB = prvGetCurrentTaskImmutable(); + traceENTER_xTaskPriorityInherit( pxMutexHolder ); /* If the mutex is taken by an interrupt, the mutex holder is NULL. Priority @@ -6591,14 +6610,14 @@ static void prvResetNextTaskUnblockTime( void ) /* If the holder of the mutex has a priority below the priority of * the task attempting to obtain the mutex then it will temporarily * inherit the priority of the task attempting to obtain the mutex. */ - if( pxMutexHolderTCB->uxPriority < pxCurrentTCB->uxPriority ) + if( pxMutexHolderTCB->uxPriority < pxConstCurrentTCB->uxPriority ) { /* Adjust the mutex holder state to account for its new * priority. Only reset the event list item value if the value is * not being used for anything else. */ if( ( listGET_LIST_ITEM_VALUE( &( pxMutexHolderTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == ( ( TickType_t ) 0U ) ) { - listSET_LIST_ITEM_VALUE( &( pxMutexHolderTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxCurrentTCB->uxPriority ); + listSET_LIST_ITEM_VALUE( &( pxMutexHolderTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxConstCurrentTCB->uxPriority ); } else { @@ -6622,7 +6641,7 @@ static void prvResetNextTaskUnblockTime( void ) } /* Inherit the priority before being moved into the new list. */ - pxMutexHolderTCB->uxPriority = pxCurrentTCB->uxPriority; + pxMutexHolderTCB->uxPriority = pxConstCurrentTCB->uxPriority; prvAddTaskToReadyList( pxMutexHolderTCB ); #if ( configNUMBER_OF_CORES > 1 ) { @@ -6638,17 +6657,17 @@ static void prvResetNextTaskUnblockTime( void ) else { /* Just inherit the priority. */ - pxMutexHolderTCB->uxPriority = pxCurrentTCB->uxPriority; + pxMutexHolderTCB->uxPriority = pxConstCurrentTCB->uxPriority; } - traceTASK_PRIORITY_INHERIT( pxMutexHolderTCB, pxCurrentTCB->uxPriority ); + traceTASK_PRIORITY_INHERIT( pxMutexHolderTCB, pxConstCurrentTCB->uxPriority ); /* Inheritance occurred. */ xReturn = pdTRUE; } else { - if( pxMutexHolderTCB->uxBasePriority < pxCurrentTCB->uxPriority ) + if( pxMutexHolderTCB->uxBasePriority < pxConstCurrentTCB->uxPriority ) { /* The base priority of the mutex holder is lower than the * priority of the task attempting to take the mutex, but the @@ -6693,7 +6712,7 @@ static void prvResetNextTaskUnblockTime( void ) * If the mutex is held by a task then it cannot be given from an * interrupt, and if a mutex is given by the holding task then it must * be the running state task. */ - configASSERT( pxTCB == pxCurrentTCB ); + configASSERT( taskTASK_IS_RUNNING( pxTCB ) == pdTRUE ); configASSERT( pxTCB->uxMutexesHeld ); ( pxTCB->uxMutexesHeld )--; @@ -6814,7 +6833,7 @@ static void prvResetNextTaskUnblockTime( void ) /* If a task has timed out because it already holds the * mutex it was trying to obtain then it cannot of inherited * its own priority. */ - configASSERT( pxTCB != pxCurrentTCB ); + configASSERT( taskTASK_IS_RUNNING( pxTCB ) == pdFALSE ); /* Disinherit the priority, remembering the previous * priority to facilitate determining the subject task's @@ -6927,7 +6946,9 @@ static void prvResetNextTaskUnblockTime( void ) if( xSchedulerRunning != pdFALSE ) { - ( pxCurrentTCB->uxCriticalNesting )++; + TCB_t * const pxConstCurrentTCB = prvGetCurrentTaskImmutable(); + + ( pxConstCurrentTCB->uxCriticalNesting )++; /* This is not the interrupt safe version of the enter critical * function so assert() if it is being called from an interrupt @@ -6935,7 +6956,7 @@ static void prvResetNextTaskUnblockTime( void ) * interrupt. Only assert if the critical nesting count is 1 to * protect against recursive calls if the assert function also uses a * critical section. */ - if( pxCurrentTCB->uxCriticalNesting == 1U ) + if( pxConstCurrentTCB->uxCriticalNesting == 1U ) { portASSERT_IF_IN_ISR(); } @@ -7037,23 +7058,25 @@ static void prvResetNextTaskUnblockTime( void ) void vTaskExitCritical( void ) { + TCB_t * const pxConstCurrentTCB = prvGetCurrentTaskImmutable(); + traceENTER_vTaskExitCritical(); if( xSchedulerRunning != pdFALSE ) { /* If pxCurrentTCB->uxCriticalNesting is zero then this function * does not match a previous call to vTaskEnterCritical(). */ - configASSERT( pxCurrentTCB->uxCriticalNesting > 0U ); + configASSERT( pxConstCurrentTCB->uxCriticalNesting > 0U ); /* This function should not be called in ISR. Use vTaskExitCriticalFromISR * to exit critical section from ISR. */ portASSERT_IF_IN_ISR(); - if( pxCurrentTCB->uxCriticalNesting > 0U ) + if( pxConstCurrentTCB->uxCriticalNesting > 0U ) { - ( pxCurrentTCB->uxCriticalNesting )--; + ( pxConstCurrentTCB->uxCriticalNesting )--; - if( pxCurrentTCB->uxCriticalNesting == 0U ) + if( pxConstCurrentTCB->uxCriticalNesting == 0U ) { portENABLE_INTERRUPTS(); } @@ -7570,13 +7593,15 @@ TickType_t uxTaskResetEventItemValue( void ) { TickType_t uxReturn; + TCB_t * const pxConstCurrentTCB = prvGetCurrentTaskImmutable(); + traceENTER_uxTaskResetEventItemValue(); - uxReturn = listGET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ) ); + uxReturn = listGET_LIST_ITEM_VALUE( &( pxConstCurrentTCB->xEventListItem ) ); /* Reset the event list item to its normal value - so it can be used with * queues and semaphores. */ - listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ), ( ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxCurrentTCB->uxPriority ) ); + listSET_LIST_ITEM_VALUE( &( pxConstCurrentTCB->xEventListItem ), ( ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxConstCurrentTCB->uxPriority ) ); traceRETURN_uxTaskResetEventItemValue( uxReturn ); @@ -7592,7 +7617,8 @@ TickType_t uxTaskResetEventItemValue( void ) traceENTER_pvTaskIncrementMutexHeldCount(); - pxTCB = pxCurrentTCB; + /* This API should be called in critical section only. */ + pxTCB = prvGetCurrentTaskImmutable(); /* If xSemaphoreCreateMutex() is called before any tasks have been created * then pxCurrentTCB will be NULL. */ @@ -7617,6 +7643,7 @@ TickType_t uxTaskResetEventItemValue( void ) { uint32_t ulReturn; BaseType_t xAlreadyYielded, xShouldBlock = pdFALSE; + TCB_t * const pxConstCurrentTCB = prvGetCurrentTask(); traceENTER_ulTaskGenericNotifyTake( uxIndexToWaitOn, xClearCountOnExit, xTicksToWait ); @@ -7633,10 +7660,10 @@ TickType_t uxTaskResetEventItemValue( void ) taskENTER_CRITICAL(); { /* Only block if the notification count is not already non-zero. */ - if( pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] == 0U ) + if( pxConstCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] == 0U ) { /* Mark this task as waiting for a notification. */ - pxCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] = taskWAITING_NOTIFICATION; + pxConstCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] = taskWAITING_NOTIFICATION; if( xTicksToWait > ( TickType_t ) 0 ) { @@ -7682,17 +7709,17 @@ TickType_t uxTaskResetEventItemValue( void ) taskENTER_CRITICAL(); { traceTASK_NOTIFY_TAKE( uxIndexToWaitOn ); - ulReturn = pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ]; + ulReturn = pxConstCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ]; if( ulReturn != 0U ) { if( xClearCountOnExit != pdFALSE ) { - pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] = ( uint32_t ) 0U; + pxConstCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] = ( uint32_t ) 0U; } else { - pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] = ulReturn - ( uint32_t ) 1; + pxConstCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] = ulReturn - ( uint32_t ) 1; } } else @@ -7700,7 +7727,7 @@ TickType_t uxTaskResetEventItemValue( void ) mtCOVERAGE_TEST_MARKER(); } - pxCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] = taskNOT_WAITING_NOTIFICATION; + pxConstCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] = taskNOT_WAITING_NOTIFICATION; } taskEXIT_CRITICAL(); @@ -7721,6 +7748,7 @@ TickType_t uxTaskResetEventItemValue( void ) TickType_t xTicksToWait ) { BaseType_t xReturn, xAlreadyYielded, xShouldBlock = pdFALSE; + TCB_t * const pxConstCurrentTCB = prvGetCurrentTask(); traceENTER_xTaskGenericNotifyWait( uxIndexToWaitOn, ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait ); @@ -7736,15 +7764,15 @@ TickType_t uxTaskResetEventItemValue( void ) taskENTER_CRITICAL(); { /* Only block if a notification is not already pending. */ - if( pxCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] != taskNOTIFICATION_RECEIVED ) + if( pxConstCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] != taskNOTIFICATION_RECEIVED ) { /* Clear bits in the task's notification value as bits may get * set by the notifying task or interrupt. This can be used * to clear the value to zero. */ - pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] &= ~ulBitsToClearOnEntry; + pxConstCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] &= ~ulBitsToClearOnEntry; /* Mark this task as waiting for a notification. */ - pxCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] = taskWAITING_NOTIFICATION; + pxConstCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] = taskWAITING_NOTIFICATION; if( xTicksToWait > ( TickType_t ) 0 ) { @@ -7795,14 +7823,14 @@ TickType_t uxTaskResetEventItemValue( void ) { /* Output the current notification value, which may or may not * have changed. */ - *pulNotificationValue = pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ]; + *pulNotificationValue = pxConstCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ]; } /* If ucNotifyValue is set then either the task never entered the * blocked state (because a notification was already pending) or the * task unblocked because of a notification. Otherwise the task * unblocked because of a timeout. */ - if( pxCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] != taskNOTIFICATION_RECEIVED ) + if( pxConstCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] != taskNOTIFICATION_RECEIVED ) { /* A notification was not received. */ xReturn = pdFALSE; @@ -7811,11 +7839,11 @@ TickType_t uxTaskResetEventItemValue( void ) { /* A notification was already pending or a notification was * received while the task was waiting. */ - pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] &= ~ulBitsToClearOnExit; + pxConstCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] &= ~ulBitsToClearOnExit; xReturn = pdTRUE; } - pxCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] = taskNOT_WAITING_NOTIFICATION; + pxConstCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] = taskNOT_WAITING_NOTIFICATION; } taskEXIT_CRITICAL(); @@ -7960,6 +7988,7 @@ TickType_t uxTaskResetEventItemValue( void ) uint8_t ucOriginalNotifyState; BaseType_t xReturn = pdPASS; UBaseType_t uxSavedInterruptStatus; + TCB_t * const pxConstCurrentTCB = prvGetCurrentTaskImmutable(); traceENTER_xTaskGenericNotifyFromISR( xTaskToNotify, uxIndexToNotify, ulValue, eAction, pulPreviousNotificationValue, pxHigherPriorityTaskWoken ); @@ -8065,7 +8094,7 @@ TickType_t uxTaskResetEventItemValue( void ) #if ( configNUMBER_OF_CORES == 1 ) { - if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + if( pxTCB->uxPriority > pxConstCurrentTCB->uxPriority ) { /* The notified task has a priority above the currently * executing task so a yield is required. */ @@ -8122,6 +8151,7 @@ TickType_t uxTaskResetEventItemValue( void ) TCB_t * pxTCB; uint8_t ucOriginalNotifyState; UBaseType_t uxSavedInterruptStatus; + TCB_t * const pxConstCurrentTCB = prvGetCurrentTaskImmutable(); traceENTER_vTaskGenericNotifyGiveFromISR( xTaskToNotify, uxIndexToNotify, pxHigherPriorityTaskWoken ); @@ -8183,7 +8213,7 @@ TickType_t uxTaskResetEventItemValue( void ) #if ( configNUMBER_OF_CORES == 1 ) { - if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + if( pxTCB->uxPriority > pxConstCurrentTCB->uxPriority ) { /* The notified task has a priority above the currently * executing task so a yield is required. */ @@ -8419,23 +8449,24 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, const TickType_t xConstTickCount = xTickCount; List_t * const pxDelayedList = pxDelayedTaskList; List_t * const pxOverflowDelayedList = pxOverflowDelayedTaskList; + TCB_t * const pxConstCurrentTCB = prvGetCurrentTaskImmutable(); #if ( INCLUDE_xTaskAbortDelay == 1 ) { /* About to enter a delayed list, so ensure the ucDelayAborted flag is * reset to pdFALSE so it can be detected as having been set to pdTRUE * when the task leaves the Blocked state. */ - pxCurrentTCB->ucDelayAborted = ( uint8_t ) pdFALSE; + pxConstCurrentTCB->ucDelayAborted = ( uint8_t ) pdFALSE; } #endif /* Remove the task from the ready list before adding it to the blocked list * as the same list item is used for both lists. */ - if( uxListRemove( &( pxCurrentTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + if( uxListRemove( &( pxConstCurrentTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) { /* The current task must be in a ready list, so there is no need to * check, and the port reset macro can be called directly. */ - portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority ); + portRESET_READY_PRIORITY( pxConstCurrentTCB->uxPriority, uxTopReadyPriority ); } else { @@ -8449,7 +8480,7 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, /* Add the task to the suspended task list instead of a delayed task * list to ensure it is not woken by a timing event. It will block * indefinitely. */ - listINSERT_END( &xSuspendedTaskList, &( pxCurrentTCB->xStateListItem ) ); + listINSERT_END( &xSuspendedTaskList, &( pxConstCurrentTCB->xStateListItem ) ); } else { @@ -8459,21 +8490,21 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, xTimeToWake = xConstTickCount + xTicksToWait; /* The list item will be inserted in wake time order. */ - listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xStateListItem ), xTimeToWake ); + listSET_LIST_ITEM_VALUE( &( pxConstCurrentTCB->xStateListItem ), xTimeToWake ); if( xTimeToWake < xConstTickCount ) { /* Wake time has overflowed. Place this item in the overflow * list. */ traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST(); - vListInsert( pxOverflowDelayedList, &( pxCurrentTCB->xStateListItem ) ); + vListInsert( pxOverflowDelayedList, &( pxConstCurrentTCB->xStateListItem ) ); } else { /* The wake time has not overflowed, so the current block list * is used. */ traceMOVED_TASK_TO_DELAYED_LIST(); - vListInsert( pxDelayedList, &( pxCurrentTCB->xStateListItem ) ); + vListInsert( pxDelayedList, &( pxConstCurrentTCB->xStateListItem ) ); /* If the task entering the blocked state was placed at the * head of the list of blocked tasks then xNextTaskUnblockTime @@ -8497,19 +8528,19 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, xTimeToWake = xConstTickCount + xTicksToWait; /* The list item will be inserted in wake time order. */ - listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xStateListItem ), xTimeToWake ); + listSET_LIST_ITEM_VALUE( &( pxConstCurrentTCB->xStateListItem ), xTimeToWake ); if( xTimeToWake < xConstTickCount ) { traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST(); /* Wake time has overflowed. Place this item in the overflow list. */ - vListInsert( pxOverflowDelayedList, &( pxCurrentTCB->xStateListItem ) ); + vListInsert( pxOverflowDelayedList, &( pxConstCurrentTCB->xStateListItem ) ); } else { traceMOVED_TASK_TO_DELAYED_LIST(); /* The wake time has not overflowed, so the current block list is used. */ - vListInsert( pxDelayedList, &( pxCurrentTCB->xStateListItem ) ); + vListInsert( pxDelayedList, &( pxConstCurrentTCB->xStateListItem ) ); /* If the task entering the blocked state was placed at the head of the * list of blocked tasks then xNextTaskUnblockTime needs to be updated