Introduce prvResetNextTaskUnblockTime() to encapsulate functionality from various places in the code into a single function.

This commit is contained in:
Richard Barry 2013-12-13 10:35:11 +00:00
parent acad916453
commit c17c65fc09

View File

@ -339,25 +339,7 @@ count overflows. */
pxDelayedTaskList = pxOverflowDelayedTaskList; \
pxOverflowDelayedTaskList = pxTemp; \
xNumOfOverflows++; \
\
if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) \
{ \
/* The new current 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 \
{ \
/* The new current 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 ) ); \
} \
prvResetNextTaskUnblockTime(); \
}
/*-----------------------------------------------------------*/
@ -483,6 +465,14 @@ static tskTCB *prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TY
#endif
/*
* Set xNextTaskUnblockTime to the time at which the next Blocked state task
* will exit the Blocked state.
*/
static void prvResetNextTaskUnblockTime( void );
/*-----------------------------------------------------------*/
signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pxTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions )
{
signed portBASE_TYPE xReturn;
@ -689,7 +679,7 @@ tskTCB * pxNewTCB;
/* The pre-delete hook is primarily for the Windows simulator,
in which Windows specific clean up operations are performed,
after which it is not possible to yield away from this task -
after which it is not possible to yield away from this task -
hence xYieldPending is used to latch that a context switch is
required. */
portPRE_TASK_DELETE_HOOK( pxTCB, &xYieldPending );
@ -697,10 +687,9 @@ tskTCB * pxNewTCB;
}
else
{
/* Reset the next expected unblock time in case it referred to the task
that has just been deleted. */
pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );
xNextTaskUnblockTime = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) );
/* Reset the next expected unblock time in case it referred to
the task that has just been deleted. */
prvResetNextTaskUnblockTime();
}
}
}
@ -1076,7 +1065,7 @@ tskTCB * pxNewTCB;
traceTASK_SUSPEND( pxTCB );
/* Remove task from the ready/delayed list and place in the
/* Remove task from the ready/delayed list and place in the
suspended list. */
if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 )
{
@ -1124,11 +1113,10 @@ tskTCB * pxNewTCB;
{
if( xSchedulerRunning != pdFALSE )
{
/* A task other than the currently running task was suspended, reset
the next expected unblock time in case it referred to the task that
is now in the Suspended state. */
pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );
xNextTaskUnblockTime = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) );
/* A task other than the currently running task was suspended,
reset the next expected unblock time in case it referred to the
task that is now in the Suspended state. */
prvResetNextTaskUnblockTime();
}
}
}
@ -1663,9 +1651,9 @@ portBASE_TYPE xSwitchRequired = pdFALSE;
taskSWITCH_DELAYED_LISTS();
}
/* See if this tick has made a timeout expire. Tasks are stored in
the queue in the order of their wake time - meaning once one task
has been found whose block time has not expired there is no need to
/* See if this tick has made a timeout expire. Tasks are stored in
the queue in the order of their wake time - meaning once one task
has been found whose block time has not expired there is no need to
look any further down the list. */
if( xConstTickCount >= xNextTaskUnblockTime )
{
@ -1673,9 +1661,9 @@ portBASE_TYPE xSwitchRequired = pdFALSE;
{
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
/* 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;
@ -1683,19 +1671,19 @@ portBASE_TYPE xSwitchRequired = pdFALSE;
}
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 must
/* 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 must
be removed from the Blocked state. */
pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );
xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) );
if( xConstTickCount < 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 must be removed from the Blocked
state - so record the item value in
/* 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 must be removed from the Blocked
state - so record the item value in
xNextTaskUnblockTime. */
xNextTaskUnblockTime = xItemValue;
break;
@ -1704,7 +1692,7 @@ portBASE_TYPE xSwitchRequired = pdFALSE;
/* It is time to remove the item from the Blocked state. */
( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
/* Is the task waiting on an event also? If so remove
/* Is the task waiting on an event also? If so remove
it from the event list. */
if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
{
@ -1715,13 +1703,13 @@ portBASE_TYPE xSwitchRequired = pdFALSE;
list. */
prvAddTaskToReadyList( pxTCB );
/* A task being unblocked cannot cause an immediate
/* A task being unblocked cannot cause an immediate
context switch if preemption is turned off. */
#if ( configUSE_PREEMPTION == 1 )
{
/* Preemption is on, but a context switch should
only be performed if the unblocked task has a
priority that is equal to or higher than the
/* Preemption is on, but a context switch should
only be performed if the unblocked task has a
priority that is equal to or higher than the
currently executing task. */
if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
{
@ -2782,6 +2770,31 @@ tskTCB *pxNewTCB;
#endif /* INCLUDE_vTaskDelete */
/*-----------------------------------------------------------*/
static void prvResetNextTaskUnblockTime( void )
{
tskTCB *pxTCB;
if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE )
{
/* The new current 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
{
/* The new current 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 ) );
}
}
/*-----------------------------------------------------------*/
#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) )
xTaskHandle xTaskGetCurrentTaskHandle( void )