]> git.sur5r.net Git - freertos/blobdiff - Source/tasks.c
Add an option for 8 byte alignment.
[freertos] / Source / tasks.c
index 74c59303559b102c86d9c4b502aae206d472b5f2..f4a7f35c7f3cd07777a95a732dac4e77bcde340b 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.0.5 - Copyright (C) 2003-2006 Richard Barry.\r
+       FreeRTOS.org V4.2.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
@@ -176,6 +176,23 @@ Changed from V4.0.4
          This has not been necessary since V4.0.1 when the xMissedYield handling\r
          was added.\r
        + Implement xTaskResumeFromISR().\r
+\r
+Changes from V4.0.5\r
+\r
+       + Added utility functions and xOverflowCount variable to facilitate the\r
+         queue.c changes.\r
+\r
+Changes from V4.1.2\r
+       \r
+       + Tasks that block on events with a timeout of portMAX_DELAY are now\r
+         blocked indefinitely if configINCLUDE_vTaskSuspend is defined. \r
+         Previously portMAX_DELAY was just the longest block time possible.\r
+\r
+Changes from V4.1.3\r
+\r
+       + Very small change made to xTaskCheckForTimeout() as a result of the \r
+       SafeRTOS testing.  This corrects the case where the function can return an\r
+       invalid value - but only in an extremely unlikely scenario.\r
 */\r
 \r
 #include <stdio.h>\r
@@ -261,13 +278,13 @@ static xList xPendingReadyList;                                                   /*< Tasks that have been readied while the
 /* File private variables. --------------------------------*/\r
 static volatile unsigned portBASE_TYPE uxCurrentNumberOfTasks  = ( unsigned portBASE_TYPE ) 0;\r
 static volatile portTickType xTickCount                                                        = ( portTickType ) 0;\r
-static unsigned portBASE_TYPE uxTopUsedPriority                                = tskIDLE_PRIORITY;\r
+static unsigned portBASE_TYPE uxTopUsedPriority                                        = tskIDLE_PRIORITY;\r
 static volatile unsigned portBASE_TYPE uxTopReadyPriority              = tskIDLE_PRIORITY;\r
 static volatile signed portBASE_TYPE xSchedulerRunning                 = pdFALSE;\r
 static volatile unsigned portBASE_TYPE uxSchedulerSuspended            = ( unsigned portBASE_TYPE ) pdFALSE;\r
 static volatile unsigned portBASE_TYPE uxMissedTicks                   = ( unsigned portBASE_TYPE ) 0;\r
 static volatile portBASE_TYPE xMissedYield                                             = ( portBASE_TYPE ) pdFALSE;\r
-\r
+static volatile portBASE_TYPE xNumOfOverflows                                  = ( portBASE_TYPE ) 0;\r
 /* Debugging and trace facilities private variables and macros. ------------*/\r
 \r
 /*\r
@@ -1281,6 +1298,7 @@ inline void vTaskIncrementTick( void )
                        pxTemp = pxDelayedTaskList;\r
                        pxDelayedTaskList = pxOverflowDelayedTaskList;\r
                        pxOverflowDelayedTaskList = pxTemp;\r
+            xNumOfOverflows++;\r
                }\r
 \r
                /* See if this tick has made a timeout expire. */\r
@@ -1412,27 +1430,61 @@ portTickType xTimeToWake;
        is the first to be woken by the event. */\r
        vListInsert( ( xList * ) pxEventList, ( xListItem * ) &( pxCurrentTCB->xEventListItem ) );\r
 \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
        /* We must remove ourselves from the ready list before adding ourselves\r
        to the blocked list as the same list item is used for both lists.  We have\r
        exclusive access to the ready lists as the scheduler is locked. */\r
        vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\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
+       #if ( INCLUDE_vTaskSuspend == 1 )\r
+       {                        \r
+               if( xTicksToWait == portMAX_DELAY )\r
+               {\r
+                       /* Add ourselves to the suspended task list instead of a delayed task\r
+                       list to ensure we are not woken by a timing event.  We will block\r
+                       indefinitely. */\r
+                       vListInsertEnd( ( xList * ) &xSuspendedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
+               }\r
+               else\r
+               {\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
+               }\r
        }\r
-       else\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
+                       /* 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
        }\r
+       #endif\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -1481,10 +1533,47 @@ portBASE_TYPE xReturn;
 \r
        return xReturn;\r
 }\r
+/*-----------------------------------------------------------*/\r
 \r
+void vTaskSetTimeOutState( xTimeOutType *pxTimeOut )\r
+{\r
+    pxTimeOut->xOverflowCount = xNumOfOverflows;\r
+    pxTimeOut->xTimeOnEntering = xTickCount;\r
+}\r
+/*-----------------------------------------------------------*/\r
 \r
+portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType *pxTimeOut, portTickType *pxTicksToWait )\r
+{\r
+portBASE_TYPE xReturn;\r
 \r
+    if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( xTickCount >= pxTimeOut->xTimeOnEntering ) )\r
+    {\r
+        /* The tick count is greater than the time at which vTaskSetTimeout() \r
+               was called, but has also overflowed since vTaskSetTimeOut() was called.\r
+        It must have wrapped all the way around and gone past us again. This\r
+        passed since vTaskSetTimeout() was called. */\r
+        xReturn = pdTRUE;\r
+    }\r
+    else if( ( xTickCount - pxTimeOut->xTimeOnEntering ) < *pxTicksToWait )\r
+    {\r
+        /* Not a genuine timeout. Adjust parameters for time remaining. */\r
+        *pxTicksToWait -= ( xTickCount - pxTimeOut->xTimeOnEntering );\r
+        vTaskSetTimeOutState( pxTimeOut );\r
+        xReturn = pdFALSE;\r
+    }\r
+    else\r
+    {\r
+        xReturn = pdTRUE;\r
+    }\r
+\r
+    return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
 \r
+void vTaskMissedYield( void )\r
+{\r
+       xMissedYield = pdTRUE;\r
+}\r
 \r
 /*\r
  * -----------------------------------------------------------\r