\r
/* The data is being left in the queue, so see if there are\r
any other tasks waiting for the data. */\r
- if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
{\r
/* Tasks that are removed from the event list will get added to\r
the pending ready list as the scheduler is still suspended. */\r
be done when the queue is unlocked later. */\r
if( pxQueue->xTxLock == queueUNLOCKED )\r
{\r
- if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
{\r
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
{\r
\r
/* The data is being left in the queue, so see if there are\r
any other tasks waiting for the data. */\r
- if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
{\r
/* Tasks that are removed from the event list will get added to\r
the pending ready list as the scheduler is still suspended. */\r
that an ISR has removed data while the queue was locked. */\r
if( pxQueue->xRxLock == queueUNLOCKED )\r
{\r
- if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
{\r
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
{\r
{\r
/* Data was posted while the queue was locked. Are any tasks\r
blocked waiting for data to become available? */\r
- if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
{\r
/* Tasks that are removed from the event list will get added to\r
the pending ready list as the scheduler is still suspended. */\r
{\r
while( pxQueue->xRxLock > queueLOCKED_UNMODIFIED )\r
{\r
- if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
{\r
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
{\r
PRIVILEGED_DATA static volatile portBASE_TYPE xMissedYield = ( portBASE_TYPE ) pdFALSE;\r
PRIVILEGED_DATA static volatile portBASE_TYPE xNumOfOverflows = ( portBASE_TYPE ) 0;\r
PRIVILEGED_DATA static unsigned portBASE_TYPE uxTaskNumber = ( unsigned portBASE_TYPE ) 0;\r
+PRIVILEGED_DATA static portTickType xNextTaskUnblockTime = ( portTickType ) portMAX_DELAY;\r
\r
#if ( configGENERATE_RUN_TIME_STATS == 1 )\r
\r
if( ( pcTraceBuffer + tskSIZE_OF_EACH_TRACE_LINE ) < pcTraceBufferEnd ) \\r
{ \\r
uxPreviousTask = pxCurrentTCB->uxTCBNumber; \\r
- *( unsigned long * ) pcTraceBuffer = ( unsigned long ) xTickCount; \\r
- pcTraceBuffer += sizeof( unsigned long ); \\r
- *( unsigned long * ) pcTraceBuffer = ( unsigned long ) uxPreviousTask; \\r
- pcTraceBuffer += sizeof( unsigned long ); \\r
+ *( unsigned long * ) pcTraceBuffer = ( unsigned long ) xTickCount; \\r
+ pcTraceBuffer += sizeof( unsigned long ); \\r
+ *( unsigned long * ) pcTraceBuffer = ( unsigned long ) uxPreviousTask; \\r
+ pcTraceBuffer += sizeof( unsigned long ); \\r
} \\r
else \\r
{ \\r
* once one tasks has been found whose timer has not expired we need not look\r
* any further down the list.\r
*/\r
-#define prvCheckDelayedTasks() \\r
-{ \\r
-register tskTCB *pxTCB; \\r
- \\r
- while( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ) ) != NULL ) \\r
- { \\r
- if( xTickCount < listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ) ) \\r
- { \\r
- break; \\r
- } \\r
- vListRemove( &( pxTCB->xGenericListItem ) ); \\r
- /* Is the task waiting on an event also? */ \\r
- if( pxTCB->xEventListItem.pvContainer ) \\r
- { \\r
- vListRemove( &( pxTCB->xEventListItem ) ); \\r
- } \\r
- prvAddTaskToReadyQueue( pxTCB ); \\r
- } \\r
+#define prvCheckDelayedTasks() \\r
+{ \\r
+register tskTCB *pxTCB; \\r
+portTickType xItemValue; \\r
+ \\r
+ /* Is the tick count greater than or equal to the wake time of the first \\r
+ task referenced from the delayed tasks list? */ \\r
+ if( xTickCount >= xNextTaskUnblockTime ) \\r
+ { \\r
+ for( ;; ) \\r
+ { \\r
+ if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) \\r
+ { \\r
+ /* The delayed list is empty. Set xNextTaskUnblockTime to the \\r
+ maximum possible value so it is extremely unlikely that the \\r
+ if( xTickCount >= xNextTaskUnblockTime ) test will pass next \\r
+ 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 at \\r
+ the head of the delayed list. This is the time at which the \\r
+ task at the head of the delayed list should be removed from \\r
+ the Blocked state. */ \\r
+ pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); \\r
+ xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ); \\r
+ \\r
+ if( xTickCount < 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 should be removed from the Blocked state - \\r
+ so record the item value in xNextTaskUnblockTime. */ \\r
+ xNextTaskUnblockTime = xItemValue; \\r
+ break; \\r
+ } \\r
+ \\r
+ /* It is time to remove the item from the Blocked state. */ \\r
+ vListRemove( &( pxTCB->xGenericListItem ) ); \\r
+ \\r
+ /* Is the task waiting on an event also? */ \\r
+ if( pxTCB->xEventListItem.pvContainer ) \\r
+ { \\r
+ vListRemove( &( pxTCB->xEventListItem ) ); \\r
+ } \\r
+ prvAddTaskToReadyQueue( pxTCB ); \\r
+ } \\r
+ } \\r
+ } \\r
}\r
/*-----------------------------------------------------------*/\r
\r
*/\r
static void prvCheckTasksWaitingTermination( void ) PRIVILEGED_FUNCTION;\r
\r
+/*\r
+ * The currently executing task is entering the Blocked state. Add the task to\r
+ * either the current or the overflow delayed task list.\r
+ */\r
+static void prvAddCurrentTaskToDelayedList( portTickType xTimeToWake ) PRIVILEGED_FUNCTION;\r
+\r
/*\r
* Allocates memory from the heap for a TCB and associated stack. Checks the\r
* allocation was successful.\r
/* Update the wake time ready for the next call. */\r
*pxPreviousWakeTime = xTimeToWake;\r
\r
- if( xShouldDelay )\r
+ if( xShouldDelay != pdFALSE )\r
{\r
traceTASK_DELAY_UNTIL();\r
\r
ourselves to the blocked list as the same list item is used for\r
both lists. */\r
vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
-\r
- /* The list item will be inserted in wake time order. */\r
- listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );\r
-\r
- if( xTimeToWake < xTickCount )\r
- {\r
- /* Wake time has overflowed. Place this item in the\r
- overflow list. */\r
- vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
- }\r
- else\r
- {\r
- /* The wake time has not overflowed, so we can use the\r
- current block list. */\r
- vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
- }\r
+ prvAddCurrentTaskToDelayedList( xTimeToWake );\r
}\r
}\r
xAlreadyYielded = xTaskResumeAll();\r
ourselves to the blocked list as the same list item is used for\r
both lists. */\r
vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
-\r
- /* The list item will be inserted in wake time order. */\r
- listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );\r
-\r
- if( xTimeToWake < xTickCount )\r
- {\r
- /* Wake time has overflowed. Place this item in the\r
- overflow list. */\r
- vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
- }\r
- else\r
- {\r
- /* The wake time has not overflowed, so we can use the\r
- current block list. */\r
- vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
- }\r
+ prvAddCurrentTaskToDelayedList( xTimeToWake );\r
}\r
xAlreadyYielded = xTaskResumeAll();\r
}\r
\r
/* Move any readied tasks from the pending list into the\r
appropriate ready list. */\r
- while( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xPendingReadyList ) ) ) != NULL )\r
+ while( listLIST_IS_EMPTY( ( xList * ) &xPendingReadyList ) == pdFALSE )\r
{\r
+ pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xPendingReadyList ) );\r
vListRemove( &( pxTCB->xEventListItem ) );\r
vListRemove( &( pxTCB->xGenericListItem ) );\r
prvAddTaskToReadyQueue( pxTCB );\r
pxDelayedTaskList = pxOverflowDelayedTaskList;\r
pxOverflowDelayedTaskList = pxTemp;\r
xNumOfOverflows++;\r
+ if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE )\r
+ {\r
+ /* The delayed list is empty. Set xNextTaskUnblockTime to the \r
+ maximum possible value so it is extremely unlikely that the \r
+ if( xTickCount >= xNextTaskUnblockTime ) test will pass\r
+ until there is an item in the delayed list. */\r
+ xNextTaskUnblockTime = portMAX_DELAY;\r
+ }\r
+ else\r
+ {\r
+ tskTCB * pxTCB;\r
+\r
+ /* The delayed list is not empty, get the value of the item at \r
+ the head of the delayed list. This is the time at which the\r
+ task at the head of the delayed list should be removed from\r
+ the Blocked state. */\r
+ pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );\r
+ xNextTaskUnblockTime = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) );\r
+ }\r
}\r
\r
/* See if this tick has made a timeout expire. */\r
/* Calculate the time at which the task should be woken if the event does\r
not occur. This may overflow but this doesn't matter. */\r
xTimeToWake = xTickCount + xTicksToWait;\r
-\r
- listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );\r
-\r
- if( xTimeToWake < xTickCount )\r
- {\r
- /* Wake time has overflowed. Place this item in the overflow list. */\r
- vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
- }\r
- else\r
- {\r
- /* The wake time has not overflowed, so we can use the current block list. */\r
- vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
- }\r
+ prvAddCurrentTaskToDelayedList( xTimeToWake );\r
}\r
}\r
#else\r
/* Calculate the time at which the task should be woken if the event does\r
not occur. This may overflow but this doesn't matter. */\r
xTimeToWake = xTickCount + xTicksToWait;\r
-\r
- listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );\r
-\r
- if( xTimeToWake < xTickCount )\r
- {\r
- /* Wake time has overflowed. Place this item in the overflow list. */\r
- vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
- }\r
- else\r
- {\r
- /* The wake time has not overflowed, so we can use the current block list. */\r
- vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
- }\r
+ prvAddCurrentTaskToDelayedList( xTimeToWake );\r
}\r
#endif\r
}\r
\r
If an event is for a queue that is locked then this function will never\r
get called - the lock count on the queue will get modified instead. This\r
- means we can always expect exclusive access to the event list here. */\r
+ means we can always expect exclusive access to the event list here. \r
+ \r
+ This function assumes that a check has already been made to ensure that\r
+ pxEventList is not empty. */\r
pxUnblockedTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );\r
vListRemove( &( pxUnblockedTCB->xEventListItem ) );\r
\r
xListIsEmpty = listLIST_IS_EMPTY( &xTasksWaitingTermination );\r
xTaskResumeAll();\r
\r
- if( !xListIsEmpty )\r
+ if( xListIsEmpty == pdFALSE )\r
{\r
tskTCB *pxTCB;\r
\r
}\r
/*-----------------------------------------------------------*/\r
\r
+static void prvAddCurrentTaskToDelayedList( portTickType xTimeToWake )\r
+{\r
+ /* The list item will be inserted in wake time order. */\r
+ listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );\r
+\r
+ if( xTimeToWake < xTickCount )\r
+ {\r
+ /* Wake time has overflowed. Place this item in the overflow list. */\r
+ vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
+ }\r
+ else\r
+ {\r
+ /* The wake time has not overflowed, so we can use the current block list. */\r
+ vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
+\r
+ /* If the task entering the blocked state was placed at the head of the\r
+ list of blocked tasks then xNextTaskUnmblockTime needs to be updated\r
+ too. */\r
+ if( xTimeToWake < xNextTaskUnblockTime )\r
+ {\r
+ xNextTaskUnblockTime = xTimeToWake;\r
+ }\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
static tskTCB *prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TYPE *puxStackBuffer )\r
{\r
tskTCB *pxNewTCB;\r