mirror of
				https://github.com/FreeRTOS/FreeRTOS-Kernel.git
				synced 2025-11-04 11:09:01 +01: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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user