mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Create macro versions of uxListRemove() and vListInsertEnd() for use in xTaskIncrementTick(). This provides a minor optimisation to remove the need for a few function calls. (#241)
Co-authored-by: alfred gedeon <28123637+alfred2g@users.noreply.github.com> Co-authored-by: Aniruddha Kanhere <60444055+AniruddhaKanhere@users.noreply.github.com>
This commit is contained in:
parent
71f5af4e0f
commit
6bf3a75c6a
|
@ -289,6 +289,86 @@ typedef struct xLIST
|
|||
( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \
|
||||
}
|
||||
|
||||
/*
|
||||
* Version of uxListRemove() that does not return a value. Provided as a slight
|
||||
* optimisation for xTaskIncrementTick() by being inline.
|
||||
*
|
||||
* Remove an item from a list. The list item has a pointer to the list that
|
||||
* it is in, so only the list item need be passed into the function.
|
||||
*
|
||||
* @param uxListRemove The item to be removed. The item will remove itself from
|
||||
* the list pointed to by it's pxContainer parameter.
|
||||
*
|
||||
* @return The number of items that remain in the list after the list item has
|
||||
* been removed.
|
||||
*
|
||||
* \page listREMOVE_ITEM listREMOVE_ITEM
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listREMOVE_ITEM( pxItemToRemove ) \
|
||||
{ \
|
||||
/* The list item knows which list it is in. Obtain the list from the list \
|
||||
* item. */ \
|
||||
List_t * const pxList = ( pxItemToRemove )->pxContainer; \
|
||||
\
|
||||
( pxItemToRemove )->pxNext->pxPrevious = ( pxItemToRemove )->pxPrevious; \
|
||||
( pxItemToRemove )->pxPrevious->pxNext = ( pxItemToRemove )->pxNext; \
|
||||
/* Make sure the index is left pointing to a valid item. */ \
|
||||
if( pxList->pxIndex == ( pxItemToRemove ) ) \
|
||||
{ \
|
||||
pxList->pxIndex = ( pxItemToRemove )->pxPrevious; \
|
||||
} \
|
||||
\
|
||||
( pxItemToRemove )->pxContainer = NULL; \
|
||||
( pxList->uxNumberOfItems )--; \
|
||||
}
|
||||
|
||||
/*
|
||||
* Inline version of vListInsertEnd() to provide slight optimisation for
|
||||
* xTaskIncrementTick().
|
||||
*
|
||||
* Insert a list item into a list. The item will be inserted in a position
|
||||
* such that it will be the last item within the list returned by multiple
|
||||
* calls to listGET_OWNER_OF_NEXT_ENTRY.
|
||||
*
|
||||
* The list member pxIndex is used to walk through a list. Calling
|
||||
* listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list.
|
||||
* Placing an item in a list using vListInsertEnd effectively places the item
|
||||
* in the list position pointed to by pxIndex. This means that every other
|
||||
* item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before
|
||||
* the pxIndex parameter again points to the item being inserted.
|
||||
*
|
||||
* @param pxList The list into which the item is to be inserted.
|
||||
*
|
||||
* @param pxNewListItem The list item to be inserted into the list.
|
||||
*
|
||||
* \page listINSERT_END listINSERT_END
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listINSERT_END( pxList, pxNewListItem ) \
|
||||
{ \
|
||||
ListItem_t * const pxIndex = ( pxList )->pxIndex; \
|
||||
\
|
||||
/* Only effective when configASSERT() is also defined, these tests may catch \
|
||||
* the list data structures being overwritten in memory. They will not catch \
|
||||
* data errors caused by incorrect configuration or use of FreeRTOS. */ \
|
||||
listTEST_LIST_INTEGRITY( ( pxList ) ); \
|
||||
listTEST_LIST_ITEM_INTEGRITY( ( pxNewListItem ) ); \
|
||||
\
|
||||
/* Insert a new list item into ( pxList ), but rather than sort the list, \
|
||||
* makes the new list item the last item to be removed by a call to \
|
||||
* listGET_OWNER_OF_NEXT_ENTRY(). */ \
|
||||
( pxNewListItem )->pxNext = pxIndex; \
|
||||
( pxNewListItem )->pxPrevious = pxIndex->pxPrevious; \
|
||||
\
|
||||
pxIndex->pxPrevious->pxNext = ( pxNewListItem ); \
|
||||
pxIndex->pxPrevious = ( pxNewListItem ); \
|
||||
\
|
||||
/* Remember which list the item is in. */ \
|
||||
( pxNewListItem )->pxContainer = ( pxList ); \
|
||||
\
|
||||
( ( pxList )->uxNumberOfItems )++; \
|
||||
}
|
||||
|
||||
/*
|
||||
* Access function to obtain the owner of the first entry in a list. Lists
|
||||
|
|
37
tasks.c
37
tasks.c
|
@ -219,7 +219,7 @@
|
|||
#define prvAddTaskToReadyList( pxTCB ) \
|
||||
traceMOVED_TASK_TO_READY_STATE( pxTCB ); \
|
||||
taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority ); \
|
||||
vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xStateListItem ) ); \
|
||||
listINSERT_END( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xStateListItem ) ); \
|
||||
tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -2233,8 +2233,9 @@ BaseType_t xTaskResumeAll( void )
|
|||
while( listLIST_IS_EMPTY( &xPendingReadyList ) == pdFALSE )
|
||||
{
|
||||
pxTCB = listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyList ) ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */
|
||||
( void ) uxListRemove( &( pxTCB->xEventListItem ) );
|
||||
( void ) uxListRemove( &( pxTCB->xStateListItem ) );
|
||||
listREMOVE_ITEM( &( pxTCB->xEventListItem ) );
|
||||
portMEMORY_BARRIER();
|
||||
listREMOVE_ITEM( &( pxTCB->xStateListItem ) );
|
||||
prvAddTaskToReadyList( pxTCB );
|
||||
|
||||
/* If the moved task has a priority higher than or equal to
|
||||
|
@ -2794,13 +2795,13 @@ BaseType_t xTaskIncrementTick( void )
|
|||
}
|
||||
|
||||
/* It is time to remove the item from the Blocked state. */
|
||||
( void ) uxListRemove( &( pxTCB->xStateListItem ) );
|
||||
listREMOVE_ITEM( &( pxTCB->xStateListItem ) );
|
||||
|
||||
/* Is the task waiting on an event also? If so remove
|
||||
* it from the event list. */
|
||||
if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
|
||||
{
|
||||
( void ) uxListRemove( &( pxTCB->xEventListItem ) );
|
||||
listREMOVE_ITEM( &( pxTCB->xEventListItem ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3127,7 +3128,7 @@ void vTaskPlaceOnUnorderedEventList( List_t * pxEventList,
|
|||
* event group implementation - and interrupts don't access event groups
|
||||
* directly (instead they access them indirectly by pending function calls to
|
||||
* the task level). */
|
||||
vListInsertEnd( pxEventList, &( pxCurrentTCB->xEventListItem ) );
|
||||
listINSERT_END( pxEventList, &( pxCurrentTCB->xEventListItem ) );
|
||||
|
||||
prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE );
|
||||
}
|
||||
|
@ -3151,7 +3152,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. */
|
||||
vListInsertEnd( pxEventList, &( pxCurrentTCB->xEventListItem ) );
|
||||
listINSERT_END( pxEventList, &( pxCurrentTCB->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
|
||||
|
@ -3188,11 +3189,11 @@ BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList )
|
|||
* pxEventList is not empty. */
|
||||
pxUnblockedTCB = listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */
|
||||
configASSERT( pxUnblockedTCB );
|
||||
( void ) uxListRemove( &( pxUnblockedTCB->xEventListItem ) );
|
||||
listREMOVE_ITEM( &( pxUnblockedTCB->xEventListItem ) );
|
||||
|
||||
if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
|
||||
{
|
||||
( void ) uxListRemove( &( pxUnblockedTCB->xStateListItem ) );
|
||||
listREMOVE_ITEM( &( pxUnblockedTCB->xStateListItem ) );
|
||||
prvAddTaskToReadyList( pxUnblockedTCB );
|
||||
|
||||
#if ( configUSE_TICKLESS_IDLE != 0 )
|
||||
|
@ -3213,7 +3214,7 @@ BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList )
|
|||
{
|
||||
/* The delayed and ready lists cannot be accessed, so hold this task
|
||||
* pending until the scheduler is resumed. */
|
||||
vListInsertEnd( &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) );
|
||||
listINSERT_END( &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) );
|
||||
}
|
||||
|
||||
if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority )
|
||||
|
@ -3252,7 +3253,7 @@ void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem,
|
|||
* event flags. */
|
||||
pxUnblockedTCB = listGET_LIST_ITEM_OWNER( pxEventListItem ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */
|
||||
configASSERT( pxUnblockedTCB );
|
||||
( void ) uxListRemove( pxEventListItem );
|
||||
listREMOVE_ITEM( pxEventListItem );
|
||||
|
||||
#if ( configUSE_TICKLESS_IDLE != 0 )
|
||||
{
|
||||
|
@ -3271,7 +3272,7 @@ void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem,
|
|||
/* Remove the task from the delayed list and add it to the ready list. The
|
||||
* scheduler is suspended so interrupts will not be accessing the ready
|
||||
* lists. */
|
||||
( void ) uxListRemove( &( pxUnblockedTCB->xStateListItem ) );
|
||||
listREMOVE_ITEM( &( pxUnblockedTCB->xStateListItem ) );
|
||||
prvAddTaskToReadyList( pxUnblockedTCB );
|
||||
|
||||
if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority )
|
||||
|
@ -4922,7 +4923,7 @@ TickType_t uxTaskResetEventItemValue( void )
|
|||
* notification then unblock it now. */
|
||||
if( ucOriginalNotifyState == taskWAITING_NOTIFICATION )
|
||||
{
|
||||
( void ) uxListRemove( &( pxTCB->xStateListItem ) );
|
||||
listREMOVE_ITEM( &( pxTCB->xStateListItem ) );
|
||||
prvAddTaskToReadyList( pxTCB );
|
||||
|
||||
/* The task should not have been on an event list. */
|
||||
|
@ -5069,14 +5070,14 @@ TickType_t uxTaskResetEventItemValue( void )
|
|||
|
||||
if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
|
||||
{
|
||||
( void ) uxListRemove( &( pxTCB->xStateListItem ) );
|
||||
listREMOVE_ITEM( &( pxTCB->xStateListItem ) );
|
||||
prvAddTaskToReadyList( pxTCB );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The delayed and ready lists cannot be accessed, so hold
|
||||
* this task pending until the scheduler is resumed. */
|
||||
vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) );
|
||||
listINSERT_END( &( xPendingReadyList ), &( pxTCB->xEventListItem ) );
|
||||
}
|
||||
|
||||
if( pxTCB->uxPriority > pxCurrentTCB->uxPriority )
|
||||
|
@ -5160,14 +5161,14 @@ TickType_t uxTaskResetEventItemValue( void )
|
|||
|
||||
if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
|
||||
{
|
||||
( void ) uxListRemove( &( pxTCB->xStateListItem ) );
|
||||
listREMOVE_ITEM( &( pxTCB->xStateListItem ) );
|
||||
prvAddTaskToReadyList( pxTCB );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The delayed and ready lists cannot be accessed, so hold
|
||||
* this task pending until the scheduler is resumed. */
|
||||
vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) );
|
||||
listINSERT_END( &( xPendingReadyList ), &( pxTCB->xEventListItem ) );
|
||||
}
|
||||
|
||||
if( pxTCB->uxPriority > pxCurrentTCB->uxPriority )
|
||||
|
@ -5303,7 +5304,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. */
|
||||
vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xStateListItem ) );
|
||||
listINSERT_END( &xSuspendedTaskList, &( pxCurrentTCB->xStateListItem ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue