#define portCLEAN_UP_TCB( pxTCB ) ( void ) pxTCB\r
#endif\r
\r
-#ifndef portPRE_DELETE_HOOK\r
- #define portPRE_DELETE_HOOK( pvTaskToDelete, pxYieldPending )\r
+#ifndef portPRE_TASK_DELETE_HOOK\r
+ #define portPRE_TASK_DELETE_HOOK( pvTaskToDelete, pxYieldPending )\r
#endif\r
\r
#ifndef portSETUP_TCB\r
void vPortDeleteThread( void *pvTaskToDelete )\r
{\r
xThreadState *pxThreadState;\r
+unsigned long ulErrorCode;\r
+\r
+ /* Remove compiler warnings if configASSERT() is not defined. */\r
+ ( void ) ulErrorCode;\r
\r
/* Find the handle of the thread being deleted. */\r
pxThreadState = ( xThreadState * ) ( *( unsigned long *) pvTaskToDelete );\r
{\r
WaitForSingleObject( pvInterruptEventMutex, INFINITE );\r
\r
- CloseHandle( pxThreadState->pvThread );\r
- TerminateThread( pxThreadState->pvThread, 0 );\r
+ ulErrorCode = TerminateThread( pxThreadState->pvThread, 0 );\r
+ configASSERT( ulErrorCode );\r
+\r
+ ulErrorCode = CloseHandle( pxThreadState->pvThread );\r
+ configASSERT( ulErrorCode );\r
\r
ReleaseMutex( pvInterruptEventMutex );\r
}\r
{\r
xThreadState *pxThreadState;\r
void *pvThread;\r
+unsigned long ulErrorCode;\r
+\r
+ /* Remove compiler warnings if configASSERT() is not defined. */\r
+ ( void ) ulErrorCode;\r
\r
/* Find the handle of the thread being deleted. */\r
pxThreadState = ( xThreadState * ) ( *( unsigned long *) pvTaskToDelete );\r
pxThreadState->pvThread = NULL;\r
\r
/* Close the thread. */\r
- CloseHandle( pvThread );\r
+ ulErrorCode = CloseHandle( pvThread );\r
+ configASSERT( ulErrorCode );\r
+\r
ExitThread( 0 );\r
}\r
/*-----------------------------------------------------------*/\r
}\r
taskEXIT_CRITICAL();\r
\r
- /* Force a reschedule if we have just deleted the current task. */\r
+ /* Force a reschedule if it is the currently running task that has just\r
+ been deleted. */\r
if( xSchedulerRunning != pdFALSE )\r
{\r
if( pxTCB == pxCurrentTCB )\r
after which it is not possible to yield away from this task - \r
hence xYieldPending is used to latch that a context switch is\r
required. */\r
- portPRE_DELETE_HOOK( pxTCB, &xYieldPending );\r
+ portPRE_TASK_DELETE_HOOK( pxTCB, &xYieldPending );\r
portYIELD_WITHIN_API();\r
}\r
+ else\r
+ {\r
+ /* Reset the next expected unblock time in case it referred to the task \r
+ that has just been deleted. */\r
+ pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );\r
+ xNextTaskUnblockTime = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) );\r
+ }\r
}\r
}\r
\r
\r
traceTASK_SUSPEND( pxTCB );\r
\r
- /* Remove task from the ready/delayed list and place in the suspended list. */\r
+ /* Remove task from the ready/delayed list and place in the \r
+ suspended list. */\r
if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 )\r
{\r
taskRESET_READY_PRIORITY( pxTCB->uxPriority );\r
}\r
}\r
}\r
+ else\r
+ {\r
+ if( xSchedulerRunning != pdFALSE )\r
+ {\r
+ /* A task other than the currently running task was suspended, reset\r
+ the next expected unblock time in case it referred to the task that\r
+ is now in the Suspended state. */\r
+ pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );\r
+ xNextTaskUnblockTime = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) );\r
+ }\r
+ }\r
}\r
\r
#endif /* INCLUDE_vTaskSuspend */\r
taskSWITCH_DELAYED_LISTS();\r
}\r
\r
- /* See if this tick has made a timeout expire. Tasks are stored in the\r
- queue in the order of their wake time - meaning once one task has been\r
- found whose block time has not expired there is no need to look any\r
- further down the list. */\r
+ /* See if this tick has made a timeout expire. Tasks are stored in \r
+ the queue in the order of their wake time - meaning once one task \r
+ has been found whose block time has not expired there is no need to \r
+ look any further down the list. */\r
if( xConstTickCount >= xNextTaskUnblockTime )\r
{\r
for( ;; )\r
{\r
if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE )\r
{\r
- /* The delayed list is empty. Set xNextTaskUnblockTime to\r
- the maximum possible value so it is extremely unlikely that\r
- the if( xTickCount >= xNextTaskUnblockTime ) test will pass\r
+ /* The delayed list is empty. Set xNextTaskUnblockTime \r
+ to the maximum possible value so it is extremely \r
+ unlikely that the \r
+ if( xTickCount >= xNextTaskUnblockTime ) test will pass\r
next time through. */\r
xNextTaskUnblockTime = portMAX_DELAY;\r
break;\r
}\r
else\r
{\r
- /* The delayed list is not empty, get the value of the item\r
- at the head of the delayed list. This is the time at which\r
- the task at the head of the delayed list must be removed\r
- from the Blocked state. */\r
+ /* The delayed list is not empty, get the value of the \r
+ item at the head of the delayed list. This is the time \r
+ at which the task at the head of the delayed list must \r
+ be removed from the Blocked state. */\r
pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );\r
xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) );\r
\r
if( xConstTickCount < xItemValue )\r
{\r
- /* It is not time to unblock this item yet, but the item\r
- value is the time at which the task at the head of the\r
- blocked list must be removed from the Blocked state -\r
- so record the item value in xNextTaskUnblockTime. */\r
+ /* It is not time to unblock this item yet, but the \r
+ item value is the time at which the task at the head \r
+ of the blocked list must be removed from the Blocked \r
+ state - so record the item value in \r
+ xNextTaskUnblockTime. */\r
xNextTaskUnblockTime = xItemValue;\r
break;\r
}\r
/* It is time to remove the item from the Blocked state. */\r
( void ) uxListRemove( &( pxTCB->xGenericListItem ) );\r
\r
- /* Is the task waiting on an event also? If so remove it\r
- from the event list. */\r
+ /* Is the task waiting on an event also? If so remove \r
+ it from the event list. */\r
if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )\r
{\r
( void ) uxListRemove( &( pxTCB->xEventListItem ) );\r
list. */\r
prvAddTaskToReadyList( pxTCB );\r
\r
- /* A task being unblocked cannot cause an immediate context\r
- switch if preemption is turned off. */\r
+ /* A task being unblocked cannot cause an immediate \r
+ context switch if preemption is turned off. */\r
#if ( configUSE_PREEMPTION == 1 )\r
{\r
- /* Preemption is on, but a context switch should only\r
- be performed if the unblocked task has a priority that\r
- is equal to or higher than the currently executing\r
- task. */\r
+ /* Preemption is on, but a context switch should \r
+ only be performed if the unblocked task has a \r
+ priority that is equal to or higher than the \r
+ currently executing task. */\r
if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )\r
{\r
xSwitchRequired = pdTRUE;\r
}\r
else\r
{\r
- /* The wake time has not overflowed, so we can use the current block list. */\r
+ /* The wake time has not overflowed, so the current block list is used. */\r
vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xGenericListItem ) );\r
\r
/* If the task entering the blocked state was placed at the head of the\r
* Insert the timer into either xActiveTimerList1, or xActiveTimerList2,\r
* depending on if the expire time causes a timer counter overflow.\r
*/\r
-static portBASE_TYPE prvInsertTimerInActiveList( xTIMER *pxTimer, portTickType xNextExpiryTime, portTickType xTimeNow, portTickType xCommandTime ) PRIVILEGED_FUNCTION;\r
+static portBASE_TYPE prvInsertTimerInActiveList( xTIMER * const pxTimer, const portTickType xNextExpiryTime, const portTickType xTimeNow, const portTickType xCommandTime ) PRIVILEGED_FUNCTION;\r
\r
/*\r
* An active timer has reached its expire time. Reload the timer if it is an\r
* auto reload timer, then call its callback.\r
*/\r
-static void prvProcessExpiredTimer( portTickType xNextExpireTime, portTickType xTimeNow ) PRIVILEGED_FUNCTION;\r
+static void prvProcessExpiredTimer( const portTickType xNextExpireTime, const portTickType xTimeNow ) PRIVILEGED_FUNCTION;\r
\r
/*\r
* The tick count has overflowed. Switch the timer lists after ensuring the\r
* current timer list does not still reference some timers.\r
*/\r
-static void prvSwitchTimerLists( portTickType xLastTime ) PRIVILEGED_FUNCTION;\r
+static void prvSwitchTimerLists( void ) PRIVILEGED_FUNCTION;\r
\r
/*\r
* Obtain the current tick count, setting *pxTimerListsWereSwitched to pdTRUE\r
* If a timer has expired, process it. Otherwise, block the timer service task\r
* until either a timer does expire or a command is received.\r
*/\r
-static void prvProcessTimerOrBlockTask( portTickType xNextExpireTime, portBASE_TYPE xListWasEmpty ) PRIVILEGED_FUNCTION;\r
+static void prvProcessTimerOrBlockTask( const portTickType xNextExpireTime, const portBASE_TYPE xListWasEmpty ) PRIVILEGED_FUNCTION;\r
\r
/*-----------------------------------------------------------*/\r
\r
#endif\r
/*-----------------------------------------------------------*/\r
\r
-static void prvProcessExpiredTimer( portTickType xNextExpireTime, portTickType xTimeNow )\r
+static void prvProcessExpiredTimer( const portTickType xNextExpireTime, const portTickType xTimeNow )\r
{\r
-xTIMER *pxTimer;\r
portBASE_TYPE xResult;\r
+xTIMER * const pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );\r
\r
/* Remove the timer from the list of active timers. A check has already\r
been performed to ensure the list is not empty. */\r
- pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );\r
( void ) uxListRemove( &( pxTimer->xTimerListItem ) );\r
traceTIMER_EXPIRED( pxTimer );\r
\r
expiry time and re-insert the timer in the list of active timers. */\r
if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE )\r
{\r
- /* This is the only time a timer is inserted into a list using\r
- a time relative to anything other than the current time. It\r
- will therefore be inserted into the correct list relative to\r
- the time this task thinks it is now, even if a command to\r
- switch lists due to a tick count overflow is already waiting in\r
- the timer queue. */\r
+ /* The timer is inserted into a list using a time relative to anything\r
+ other than the current time. It will therefore be inserted into the\r
+ correct list relative to the time this task thinks it is now. */\r
if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) == pdTRUE )\r
{\r
/* The timer expired before it was added to the active timer\r
}\r
/*-----------------------------------------------------------*/\r
\r
-static void prvProcessTimerOrBlockTask( portTickType xNextExpireTime, portBASE_TYPE xListWasEmpty )\r
+static void prvProcessTimerOrBlockTask( const portTickType xNextExpireTime, const portBASE_TYPE xListWasEmpty )\r
{\r
portTickType xTimeNow;\r
portBASE_TYPE xTimerListsWereSwitched;\r
\r
if( xTimeNow < xLastTime )\r
{\r
- prvSwitchTimerLists( xLastTime );\r
+ prvSwitchTimerLists();\r
*pxTimerListsWereSwitched = pdTRUE;\r
}\r
else\r
}\r
/*-----------------------------------------------------------*/\r
\r
-static portBASE_TYPE prvInsertTimerInActiveList( xTIMER *pxTimer, portTickType xNextExpiryTime, portTickType xTimeNow, portTickType xCommandTime )\r
+static portBASE_TYPE prvInsertTimerInActiveList( xTIMER * const pxTimer, const portTickType xNextExpiryTime, const portTickType xTimeNow, const portTickType xCommandTime )\r
{\r
portBASE_TYPE xProcessTimerNow = pdFALSE;\r
\r
/* Start or restart a timer. */\r
if( prvInsertTimerInActiveList( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.u.xTimerParameters.xMessageValue ) == pdTRUE )\r
{\r
- /* The timer expired before it was added to the active timer\r
- list. Process it now. */\r
+ /* The timer expired before it was added to the active\r
+ timer list. Process it now. */\r
pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer );\r
+ traceTIMER_EXPIRED( pxTimer );\r
\r
if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE )\r
{\r
}\r
/*-----------------------------------------------------------*/\r
\r
-static void prvSwitchTimerLists( portTickType xLastTime )\r
+static void prvSwitchTimerLists( void )\r
{\r
portTickType xNextExpireTime, xReloadTime;\r
xList *pxTemp;\r
xTIMER *pxTimer;\r
portBASE_TYPE xResult;\r
\r
- /* Remove compiler warnings if configASSERT() is not defined. */\r
- ( void ) xLastTime;\r
-\r
/* The tick count has overflowed. The timer lists must be switched.\r
If there are any timers still referenced from the current timer list\r
then they must have expired and should be processed before the lists\r
/* Remove the timer from the list. */\r
pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );\r
( void ) uxListRemove( &( pxTimer->xTimerListItem ) );\r
+ traceTIMER_EXPIRED( pxTimer );\r
\r
/* Execute its callback, then send a command to restart the timer if\r
it is an auto-reload timer. It cannot be restarted here as the lists\r
}\r
/*-----------------------------------------------------------*/\r
\r
-void *pvTimerGetTimerID( xTimerHandle xTimer )\r
+void *pvTimerGetTimerID( const xTimerHandle xTimer )\r
{\r
-xTIMER *pxTimer = ( xTIMER * ) xTimer;\r
+xTIMER * const pxTimer = ( xTIMER * const ) xTimer;\r
\r
return pxTimer->pvTimerID;\r
}\r