mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Some time and code size optimisations.
This commit is contained in:
parent
1374a17f73
commit
c26b230d28
|
@ -222,7 +222,7 @@ static void prvCheckPendingReadyList( void )
|
|||
/* Are there any co-routines waiting to get moved to the ready list? These
|
||||
are co-routines that have been readied by an ISR. The ISR cannot access
|
||||
the ready lists itself. */
|
||||
while( !listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) )
|
||||
while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE )
|
||||
{
|
||||
corCRCB *pxUnblockedCRCB;
|
||||
|
||||
|
@ -263,8 +263,10 @@ corCRCB *pxCRCB;
|
|||
}
|
||||
|
||||
/* See if this tick has made a timeout expire. */
|
||||
while( ( pxCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ) ) != NULL )
|
||||
while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE )
|
||||
{
|
||||
pxCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList );
|
||||
|
||||
if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) )
|
||||
{
|
||||
/* Timeout not yet expired. */
|
||||
|
@ -352,7 +354,8 @@ corCRCB *pxUnblockedCRCB;
|
|||
signed portBASE_TYPE xReturn;
|
||||
|
||||
/* This function is called from within an interrupt. It can only access
|
||||
event lists and the pending ready list. */
|
||||
event lists and the pending ready list. This function assumes that a
|
||||
check has already been made to ensure pxEventList is not empty. */
|
||||
pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
|
||||
vListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
||||
vListInsertEnd( ( xList * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );
|
||||
|
|
|
@ -214,7 +214,7 @@ xList * const pxConstList = pxList; \
|
|||
* \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( ( pxList->uxNumberOfItems != ( unsigned portBASE_TYPE ) 0 ) ? ( (&( pxList->xListEnd ))->pxNext->pvOwner ) : ( NULL ) )
|
||||
#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( (&( pxList->xListEnd ))->pxNext->pvOwner )
|
||||
|
||||
/*
|
||||
* Check to see if a list item is within a list. The list item maintains a
|
||||
|
|
|
@ -697,7 +697,7 @@ xTimeOutType xTimeOut;
|
|||
|
||||
/* The data is being left in the queue, so see if there are
|
||||
any other tasks waiting for the data. */
|
||||
if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
|
||||
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
|
||||
{
|
||||
/* Tasks that are removed from the event list will get added to
|
||||
the pending ready list as the scheduler is still suspended. */
|
||||
|
@ -790,7 +790,7 @@ unsigned portBASE_TYPE uxSavedInterruptStatus;
|
|||
be done when the queue is unlocked later. */
|
||||
if( pxQueue->xTxLock == queueUNLOCKED )
|
||||
{
|
||||
if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
|
||||
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
|
||||
{
|
||||
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
|
||||
{
|
||||
|
@ -880,7 +880,7 @@ signed char *pcOriginalReadPosition;
|
|||
|
||||
/* The data is being left in the queue, so see if there are
|
||||
any other tasks waiting for the data. */
|
||||
if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
|
||||
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
|
||||
{
|
||||
/* Tasks that are removed from the event list will get added to
|
||||
the pending ready list as the scheduler is still suspended. */
|
||||
|
@ -988,7 +988,7 @@ unsigned portBASE_TYPE uxSavedInterruptStatus;
|
|||
that an ISR has removed data while the queue was locked. */
|
||||
if( pxQueue->xRxLock == queueUNLOCKED )
|
||||
{
|
||||
if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )
|
||||
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
|
||||
{
|
||||
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
|
||||
{
|
||||
|
@ -1117,7 +1117,7 @@ static void prvUnlockQueue( xQueueHandle pxQueue )
|
|||
{
|
||||
/* Data was posted while the queue was locked. Are any tasks
|
||||
blocked waiting for data to become available? */
|
||||
if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
|
||||
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
|
||||
{
|
||||
/* Tasks that are removed from the event list will get added to
|
||||
the pending ready list as the scheduler is still suspended. */
|
||||
|
@ -1145,7 +1145,7 @@ static void prvUnlockQueue( xQueueHandle pxQueue )
|
|||
{
|
||||
while( pxQueue->xRxLock > queueLOCKED_UNMODIFIED )
|
||||
{
|
||||
if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )
|
||||
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
|
||||
{
|
||||
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
|
||||
{
|
||||
|
|
163
Source/tasks.c
163
Source/tasks.c
|
@ -161,6 +161,7 @@ PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxMissedTicks = ( unsi
|
|||
PRIVILEGED_DATA static volatile portBASE_TYPE xMissedYield = ( portBASE_TYPE ) pdFALSE;
|
||||
PRIVILEGED_DATA static volatile portBASE_TYPE xNumOfOverflows = ( portBASE_TYPE ) 0;
|
||||
PRIVILEGED_DATA static unsigned portBASE_TYPE uxTaskNumber = ( unsigned portBASE_TYPE ) 0;
|
||||
PRIVILEGED_DATA static portTickType xNextTaskUnblockTime = ( portTickType ) portMAX_DELAY;
|
||||
|
||||
#if ( configGENERATE_RUN_TIME_STATS == 1 )
|
||||
|
||||
|
@ -268,14 +269,45 @@ PRIVILEGED_DATA static unsigned portBASE_TYPE uxTaskNumber = ( unsigned po
|
|||
#define prvCheckDelayedTasks() \
|
||||
{ \
|
||||
register tskTCB *pxTCB; \
|
||||
portTickType xItemValue; \
|
||||
\
|
||||
while( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ) ) != NULL ) \
|
||||
/* Is the tick count greater than or equal to the wake time of the first \
|
||||
task referenced from the delayed tasks list? */ \
|
||||
if( xTickCount >= xNextTaskUnblockTime ) \
|
||||
{ \
|
||||
if( xTickCount < listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ) ) \
|
||||
for( ;; ) \
|
||||
{ \
|
||||
if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) \
|
||||
{ \
|
||||
/* The delayed list is empty. Set xNextTaskUnblockTime to the \
|
||||
maximum possible value so it is extremely unlikely that the \
|
||||
if( xTickCount >= xNextTaskUnblockTime ) test will pass next \
|
||||
time through. */ \
|
||||
xNextTaskUnblockTime = portMAX_DELAY; \
|
||||
break; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* The delayed list is not empty, get the value of the item at \
|
||||
the head of the delayed list. This is the time at which the \
|
||||
task at the head of the delayed list should be removed from \
|
||||
the Blocked state. */ \
|
||||
pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); \
|
||||
xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ); \
|
||||
\
|
||||
if( xTickCount < xItemValue ) \
|
||||
{ \
|
||||
/* It is not time to unblock this item yet, but the item \
|
||||
value is the time at which the task at the head of the \
|
||||
blocked list should be removed from the Blocked state - \
|
||||
so record the item value in xNextTaskUnblockTime. */ \
|
||||
xNextTaskUnblockTime = xItemValue; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
/* It is time to remove the item from the Blocked state. */ \
|
||||
vListRemove( &( pxTCB->xGenericListItem ) ); \
|
||||
\
|
||||
/* Is the task waiting on an event also? */ \
|
||||
if( pxTCB->xEventListItem.pvContainer ) \
|
||||
{ \
|
||||
|
@ -283,6 +315,8 @@ register tskTCB *pxTCB; \
|
|||
} \
|
||||
prvAddTaskToReadyQueue( pxTCB ); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -342,6 +376,12 @@ static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters );
|
|||
*/
|
||||
static void prvCheckTasksWaitingTermination( void ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* The currently executing task is entering the Blocked state. Add the task to
|
||||
* either the current or the overflow delayed task list.
|
||||
*/
|
||||
static void prvAddCurrentTaskToDelayedList( portTickType xTimeToWake ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Allocates memory from the heap for a TCB and associated stack. Checks the
|
||||
* allocation was successful.
|
||||
|
@ -637,7 +677,7 @@ tskTCB * pxNewTCB;
|
|||
/* Update the wake time ready for the next call. */
|
||||
*pxPreviousWakeTime = xTimeToWake;
|
||||
|
||||
if( xShouldDelay )
|
||||
if( xShouldDelay != pdFALSE )
|
||||
{
|
||||
traceTASK_DELAY_UNTIL();
|
||||
|
||||
|
@ -645,22 +685,7 @@ tskTCB * pxNewTCB;
|
|||
ourselves to the blocked list as the same list item is used for
|
||||
both lists. */
|
||||
vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
|
||||
|
||||
/* The list item will be inserted in wake time order. */
|
||||
listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );
|
||||
|
||||
if( xTimeToWake < xTickCount )
|
||||
{
|
||||
/* Wake time has overflowed. Place this item in the
|
||||
overflow list. */
|
||||
vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The wake time has not overflowed, so we can use the
|
||||
current block list. */
|
||||
vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
|
||||
}
|
||||
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||
}
|
||||
}
|
||||
xAlreadyYielded = xTaskResumeAll();
|
||||
|
@ -706,22 +731,7 @@ tskTCB * pxNewTCB;
|
|||
ourselves to the blocked list as the same list item is used for
|
||||
both lists. */
|
||||
vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
|
||||
|
||||
/* The list item will be inserted in wake time order. */
|
||||
listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );
|
||||
|
||||
if( xTimeToWake < xTickCount )
|
||||
{
|
||||
/* Wake time has overflowed. Place this item in the
|
||||
overflow list. */
|
||||
vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The wake time has not overflowed, so we can use the
|
||||
current block list. */
|
||||
vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
|
||||
}
|
||||
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||
}
|
||||
xAlreadyYielded = xTaskResumeAll();
|
||||
}
|
||||
|
@ -1125,8 +1135,9 @@ signed portBASE_TYPE xAlreadyYielded = pdFALSE;
|
|||
|
||||
/* Move any readied tasks from the pending list into the
|
||||
appropriate ready list. */
|
||||
while( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xPendingReadyList ) ) ) != NULL )
|
||||
while( listLIST_IS_EMPTY( ( xList * ) &xPendingReadyList ) == pdFALSE )
|
||||
{
|
||||
pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xPendingReadyList ) );
|
||||
vListRemove( &( pxTCB->xEventListItem ) );
|
||||
vListRemove( &( pxTCB->xGenericListItem ) );
|
||||
prvAddTaskToReadyQueue( pxTCB );
|
||||
|
@ -1413,6 +1424,25 @@ void vTaskIncrementTick( void )
|
|||
pxDelayedTaskList = pxOverflowDelayedTaskList;
|
||||
pxOverflowDelayedTaskList = pxTemp;
|
||||
xNumOfOverflows++;
|
||||
if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE )
|
||||
{
|
||||
/* The delayed list is empty. Set xNextTaskUnblockTime to the
|
||||
maximum possible value so it is extremely unlikely that the
|
||||
if( xTickCount >= xNextTaskUnblockTime ) test will pass
|
||||
until there is an item in the delayed list. */
|
||||
xNextTaskUnblockTime = portMAX_DELAY;
|
||||
}
|
||||
else
|
||||
{
|
||||
tskTCB * pxTCB;
|
||||
|
||||
/* The delayed list is not empty, get the value of the item at
|
||||
the head of the delayed list. This is the time at which the
|
||||
task at the head of the delayed list should be removed from
|
||||
the Blocked state. */
|
||||
pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );
|
||||
xNextTaskUnblockTime = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* See if this tick has made a timeout expire. */
|
||||
|
@ -1672,19 +1702,7 @@ portTickType xTimeToWake;
|
|||
/* Calculate the time at which the task should be woken if the event does
|
||||
not occur. This may overflow but this doesn't matter. */
|
||||
xTimeToWake = xTickCount + xTicksToWait;
|
||||
|
||||
listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );
|
||||
|
||||
if( xTimeToWake < xTickCount )
|
||||
{
|
||||
/* Wake time has overflowed. Place this item in the overflow list. */
|
||||
vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The wake time has not overflowed, so we can use the current block list. */
|
||||
vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
|
||||
}
|
||||
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
@ -1692,19 +1710,7 @@ portTickType xTimeToWake;
|
|||
/* Calculate the time at which the task should be woken if the event does
|
||||
not occur. This may overflow but this doesn't matter. */
|
||||
xTimeToWake = xTickCount + xTicksToWait;
|
||||
|
||||
listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );
|
||||
|
||||
if( xTimeToWake < xTickCount )
|
||||
{
|
||||
/* Wake time has overflowed. Place this item in the overflow list. */
|
||||
vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The wake time has not overflowed, so we can use the current block list. */
|
||||
vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
|
||||
}
|
||||
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1724,7 +1730,10 @@ portBASE_TYPE xReturn;
|
|||
|
||||
If an event is for a queue that is locked then this function will never
|
||||
get called - the lock count on the queue will get modified instead. This
|
||||
means we can always expect exclusive access to the event list here. */
|
||||
means we can always expect exclusive access to the event list here.
|
||||
|
||||
This function assumes that a check has already been made to ensure that
|
||||
pxEventList is not empty. */
|
||||
pxUnblockedTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
|
||||
vListRemove( &( pxUnblockedTCB->xEventListItem ) );
|
||||
|
||||
|
@ -2020,7 +2029,7 @@ static void prvCheckTasksWaitingTermination( void )
|
|||
xListIsEmpty = listLIST_IS_EMPTY( &xTasksWaitingTermination );
|
||||
xTaskResumeAll();
|
||||
|
||||
if( !xListIsEmpty )
|
||||
if( xListIsEmpty == pdFALSE )
|
||||
{
|
||||
tskTCB *pxTCB;
|
||||
|
||||
|
@ -2041,6 +2050,32 @@ static void prvCheckTasksWaitingTermination( void )
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvAddCurrentTaskToDelayedList( portTickType xTimeToWake )
|
||||
{
|
||||
/* The list item will be inserted in wake time order. */
|
||||
listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );
|
||||
|
||||
if( xTimeToWake < xTickCount )
|
||||
{
|
||||
/* Wake time has overflowed. Place this item in the overflow list. */
|
||||
vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The wake time has not overflowed, so we can use the current block list. */
|
||||
vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
|
||||
|
||||
/* If the task entering the blocked state was placed at the head of the
|
||||
list of blocked tasks then xNextTaskUnmblockTime needs to be updated
|
||||
too. */
|
||||
if( xTimeToWake < xNextTaskUnblockTime )
|
||||
{
|
||||
xNextTaskUnblockTime = xTimeToWake;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static tskTCB *prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TYPE *puxStackBuffer )
|
||||
{
|
||||
tskTCB *pxNewTCB;
|
||||
|
|
Loading…
Reference in a new issue