|
|
|
@ -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 )
|
|
|
|
|