]> git.sur5r.net Git - freertos/blobdiff - Source/tasks.c
Remove .bak files.
[freertos] / Source / tasks.c
index ff4bdcef6dfb6ec21a631222af12225978094558..a605b99f2a380651a0a2c766ca17a2a39bd5f7a5 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.3.1 - Copyright (C) 2003-2007 Richard Barry.\r
+       FreeRTOS.org V4.7.0 - Copyright (C) 2003-2007 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
@@ -28,8 +28,9 @@
        and contact details.  Please ensure to read the configuration and relevant\r
        port sections of the online documentation.\r
 \r
-       Also see http://www.SafeRTOS.com for an IEC 61508 compliant version, along\r
-       with development and support options.\r
+       Also see http://www.SafeRTOS.com a version that has been certified for use\r
+       in safety critical systems, plus commercial licensing, development and\r
+       support options.\r
        ***************************************************************************\r
 */\r
 \r
@@ -229,10 +230,6 @@ Changes since V4.3.1:
        #define configMAX_TASK_NAME_LEN 16\r
 #endif\r
 \r
-#ifndef INCLUDE_xTaskGetCurrentTaskHandle\r
-       #define INCLUDE_xTaskGetCurrentTaskHandle 0\r
-#endif\r
-\r
 #ifndef configIDLE_SHOULD_YIELD\r
        #define configIDLE_SHOULD_YIELD         1\r
 #endif\r
@@ -261,9 +258,16 @@ typedef struct tskTaskControlBlock
        xListItem                               xEventListItem;         /*< List item used to place the TCB in event lists. */\r
        unsigned portBASE_TYPE  uxPriority;                     /*< The priority of the task where 0 is the lowest priority. */\r
        portSTACK_TYPE                  *pxStack;                       /*< Points to the start of the stack. */\r
-       unsigned portBASE_TYPE  uxTCBNumber;            /*< This is used for tracing the scheduler and making debugging easier only. */\r
        signed portCHAR                 pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created.  Facilitates debugging only. */\r
-       unsigned portSHORT              usStackDepth;           /*< Total depth of the stack (when empty).  This is defined as the number of variables the stack can hold, not the number of bytes. */\r
+\r
+       #if ( configUSE_TRACE_FACILITY == 1 )\r
+               unsigned portBASE_TYPE  uxTCBNumber;            /*< This is used for tracing the scheduler and making debugging easier only. */\r
+       #endif  \r
+               \r
+       #if ( configUSE_MUTEXES == 1 )\r
+               unsigned portBASE_TYPE uxBasePriority;\r
+       #endif\r
+               \r
 } tskTCB;\r
 \r
 /*lint -e956 */\r
@@ -429,7 +433,7 @@ register tskTCB *pxTCB;                                                                                                                                                                                             \
  * Utility to ready a TCB for a given task.  Mainly just copies the parameters\r
  * into the TCB structure.\r
  */\r
-static void prvInitialiseTCBVariables( tskTCB *pxTCB, unsigned portSHORT usStackDepth, const signed portCHAR * const pcName, unsigned portBASE_TYPE uxPriority );\r
+static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed portCHAR * const pcName, unsigned portBASE_TYPE uxPriority );\r
 \r
 /*\r
  * Utility to ready all the lists used by the scheduler.  This is called\r
@@ -485,7 +489,7 @@ static tskTCB *prvAllocateTCBAndStack( unsigned portSHORT usStackDepth );
  */\r
 #if ( configUSE_TRACE_FACILITY == 1 )\r
 \r
-       static void prvListTaskWithinSingleList( signed portCHAR *pcWriteBuffer, xList *pxList, signed portCHAR cStatus );\r
+       static void prvListTaskWithinSingleList( const signed portCHAR *pcWriteBuffer, xList *pxList, signed portCHAR cStatus );\r
 \r
 #endif\r
 \r
@@ -496,7 +500,7 @@ static tskTCB *prvAllocateTCBAndStack( unsigned portSHORT usStackDepth );
  */\r
 #if ( configUSE_TRACE_FACILITY == 1 )\r
 \r
-       unsigned portSHORT usTaskCheckFreeStackSpace( const unsigned portCHAR *pucStackByte );\r
+       unsigned portSHORT usTaskCheckFreeStackSpace( const unsigned portCHAR * pucStackByte );\r
 \r
 #endif\r
 \r
@@ -524,7 +528,9 @@ signed portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode, const signed portCHAR
 {\r
 signed portBASE_TYPE xReturn;\r
 tskTCB * pxNewTCB;\r
-static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberate - this is guarded before use. */\r
+#if ( configUSE_TRACE_FACILITY == 1 )\r
+       static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberate - this is guarded before use. */\r
+#endif\r
 \r
        /* Allocate the memory required by the TCB and stack for the new task.\r
        checking that the allocation was successful. */\r
@@ -535,7 +541,7 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
                portSTACK_TYPE *pxTopOfStack;\r
 \r
                /* Setup the newly allocated TCB with the initial state of the task. */\r
-               prvInitialiseTCBVariables( pxNewTCB, usStackDepth, pcName, uxPriority );\r
+               prvInitialiseTCBVariables( pxNewTCB, pcName, uxPriority );\r
 \r
                /* Calculate the top of stack address.  This depends on whether the\r
                stack grows from high memory to low (as per the 80x86) or visa versa.\r
@@ -543,7 +549,7 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
                required by the port. */\r
                #if portSTACK_GROWTH < 0\r
                {\r
-                       pxTopOfStack = pxNewTCB->pxStack + ( pxNewTCB->usStackDepth - 1 );\r
+                       pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 );\r
                }\r
                #else\r
                {\r
@@ -593,9 +599,13 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
                                uxTopUsedPriority = pxNewTCB->uxPriority;\r
                        }\r
 \r
-                       /* Add a counter into the TCB for tracing only. */\r
-                       pxNewTCB->uxTCBNumber = uxTaskNumber;\r
-                       uxTaskNumber++;\r
+                       #if ( configUSE_TRACE_FACILITY == 1 )\r
+                       {\r
+                               /* Add a counter into the TCB for tracing only. */\r
+                               pxNewTCB->uxTCBNumber = uxTaskNumber;\r
+                               uxTaskNumber++;\r
+                       }\r
+                       #endif\r
 \r
                        prvAddTaskToReadyQueue( pxNewTCB );\r
 \r
@@ -695,7 +705,7 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
 \r
 #if ( INCLUDE_vTaskDelayUntil == 1 )\r
 \r
-       void vTaskDelayUntil( portTickType *pxPreviousWakeTime, portTickType xTimeIncrement )\r
+       void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement )\r
        {\r
        portTickType xTimeToWake;\r
        portBASE_TYPE xAlreadyYielded, xShouldDelay = pdFALSE;\r
@@ -867,13 +877,22 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
                        /* If null is passed in here then we are changing the\r
                        priority of the calling function. */\r
                        pxTCB = prvGetTCBFromHandle( pxTask );\r
-                       uxCurrentPriority = pxTCB->uxPriority;\r
+                       \r
+                       #if ( configUSE_MUTEXES == 1 )\r
+                       {\r
+                               uxCurrentPriority = pxTCB->uxBasePriority;\r
+                       }\r
+                       #else\r
+                       {\r
+                               uxCurrentPriority = pxTCB->uxPriority;\r
+                       }\r
+                       #endif\r
 \r
                        if( uxCurrentPriority != uxNewPriority )\r
                        {\r
                                /* The priority change may have readied a task of higher\r
                                priority than the calling task. */\r
-                               if( uxNewPriority > pxCurrentTCB->uxPriority ) \r
+                               if( uxNewPriority > uxCurrentPriority ) \r
                                {\r
                                        if( pxTask != NULL )\r
                                        {\r
@@ -891,8 +910,27 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
                                        xYieldRequired = pdTRUE;\r
                                }\r
                        \r
-                               pxTCB->uxPriority = uxNewPriority;\r
-                               listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxNewPriority );\r
+                               \r
+\r
+                               #if ( configUSE_MUTEXES == 1 )\r
+                               {\r
+                                       /* Only change the priority being used if the task is not\r
+                                       currently using an inherited priority. */\r
+                                       if( pxTCB->uxBasePriority == pxTCB->uxPriority )\r
+                                       {\r
+                                               pxTCB->uxPriority = uxNewPriority;\r
+                                       }\r
+                                       \r
+                                       /* The base priority gets set whatever. */\r
+                                       pxTCB->uxBasePriority = uxNewPriority;                                  \r
+                               }\r
+                               #else\r
+                               {\r
+                                       pxTCB->uxPriority = uxNewPriority;\r
+                               }\r
+                               #endif\r
+\r
+                               listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( configMAX_PRIORITIES - ( portTickType ) uxNewPriority ) );\r
 \r
                                /* If the task is in the blocked or suspended list we need do\r
                                nothing more than change it's priority variable. However, if\r
@@ -1051,7 +1089,7 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
                        {\r
                                /* We cannot access the delayed or ready lists, so will hold this\r
                                task pending until the scheduler is resumed, at which point a\r
-                               yield will be preformed if necessary. */\r
+                               yield will be performed if necessary. */\r
                                vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxTCB->xEventListItem ) );\r
                        }\r
                }\r
@@ -1457,7 +1495,7 @@ void vTaskSwitchContext( void )
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void vTaskPlaceOnEventList( xList *pxEventList, portTickType xTicksToWait )\r
+void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait )\r
 {\r
 portTickType xTimeToWake;\r
 \r
@@ -1527,7 +1565,7 @@ portTickType xTimeToWake;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-signed portBASE_TYPE xTaskRemoveFromEventList( const xList *pxEventList )\r
+signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList )\r
 {\r
 tskTCB *pxUnblockedTCB;\r
 portBASE_TYPE xReturn;\r
@@ -1574,14 +1612,14 @@ portBASE_TYPE xReturn;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void vTaskSetTimeOutState( xTimeOutType *pxTimeOut )\r
+void vTaskSetTimeOutState( xTimeOutType * const pxTimeOut )\r
 {\r
     pxTimeOut->xOverflowCount = xNumOfOverflows;\r
     pxTimeOut->xTimeOnEntering = xTickCount;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType *pxTimeOut, portTickType * const pxTicksToWait )\r
+portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait )\r
 {\r
 portBASE_TYPE xReturn;\r
 \r
@@ -1701,10 +1739,8 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
 \r
 \r
 \r
-static void prvInitialiseTCBVariables( tskTCB *pxTCB, unsigned portSHORT usStackDepth, const signed portCHAR * const pcName, unsigned portBASE_TYPE uxPriority )\r
+static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed portCHAR * const pcName, unsigned portBASE_TYPE uxPriority )\r
 {\r
-       pxTCB->usStackDepth = usStackDepth;\r
-\r
        /* Store the function name in the TCB. */\r
        strncpy( ( char * ) pxTCB->pcTaskName, ( const char * ) pcName, ( unsigned portSHORT ) configMAX_TASK_NAME_LEN );\r
        pxTCB->pcTaskName[ ( unsigned portSHORT ) configMAX_TASK_NAME_LEN - ( unsigned portSHORT ) 1 ] = '\0';\r
@@ -1716,6 +1752,11 @@ static void prvInitialiseTCBVariables( tskTCB *pxTCB, unsigned portSHORT usStack
        }\r
 \r
        pxTCB->uxPriority = uxPriority;\r
+       #if ( configUSE_MUTEXES == 1 )\r
+       {\r
+               pxTCB->uxBasePriority = uxPriority;\r
+       }\r
+       #endif\r
 \r
        vListInitialiseItem( &( pxTCB->xGenericListItem ) );\r
        vListInitialiseItem( &( pxTCB->xEventListItem ) );\r
@@ -1831,7 +1872,7 @@ tskTCB *pxNewTCB;
 \r
 #if ( configUSE_TRACE_FACILITY == 1 )\r
 \r
-       static void prvListTaskWithinSingleList( signed portCHAR *pcWriteBuffer, xList *pxList, signed portCHAR cStatus )\r
+       static void prvListTaskWithinSingleList( const signed portCHAR *pcWriteBuffer, xList *pxList, signed portCHAR cStatus )\r
        {\r
        volatile tskTCB *pxNextTCB, *pxFirstTCB;\r
        static portCHAR pcStatusString[ 50 ];\r
@@ -1853,7 +1894,7 @@ tskTCB *pxNewTCB;
 /*-----------------------------------------------------------*/\r
 \r
 #if ( configUSE_TRACE_FACILITY == 1 )\r
-       unsigned portSHORT usTaskCheckFreeStackSpace( const unsigned portCHAR *pucStackByte )\r
+       unsigned portSHORT usTaskCheckFreeStackSpace( const unsigned portCHAR * pucStackByte )\r
        {\r
        register unsigned portSHORT usCount = 0;\r
 \r
@@ -1933,4 +1974,63 @@ tskTCB *pxNewTCB;
 \r
 #endif\r
 \r
+#if ( configUSE_MUTEXES == 1 )\r
+       \r
+       void vTaskPriorityInherit( xTaskHandle * const pxMutexHolder )\r
+       {\r
+       tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder;\r
+\r
+               if( pxTCB->uxPriority < pxCurrentTCB->uxPriority )\r
+               {\r
+                       /* Adjust the mutex holder state to account for its new priority. */\r
+                       listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) pxCurrentTCB->uxPriority );\r
+\r
+                       /* If the task being modified is in the read state it will need to\r
+                       be moved in to a new list. */\r
+                       if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ) )\r
+                       {\r
+                               vListRemove( &( pxTCB->xGenericListItem ) );\r
+\r
+                               /* Inherit the priority before being moved into the new list. */\r
+                               pxTCB->uxPriority = pxCurrentTCB->uxPriority;\r
+                               prvAddTaskToReadyQueue( pxTCB );\r
+                       }\r
+                       else\r
+                       {\r
+                               /* Just inherit the priority. */\r
+                               pxTCB->uxPriority = pxCurrentTCB->uxPriority;\r
+                       }\r
+               }\r
+       }\r
+\r
+#endif\r
+\r
+#if ( configUSE_MUTEXES == 1 ) \r
+\r
+       void vTaskPriorityDisinherit( xTaskHandle * const pxMutexHolder )\r
+       {\r
+       tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder;\r
+\r
+               if( pxMutexHolder != NULL )\r
+               {\r
+                       if( pxTCB->uxPriority != pxTCB->uxBasePriority )\r
+                       {\r
+                               /* We must be the running task to be able to give the mutex back.\r
+                               Remove ourselves from the ready list we currently appear in. */\r
+                               vListRemove( &( pxTCB->xGenericListItem ) );\r
+\r
+                               /* Disinherit the priority before adding ourselves into the new\r
+                               ready list. */\r
+                               pxTCB->uxPriority = pxTCB->uxBasePriority;\r
+                               listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) pxTCB->uxPriority );\r
+                               prvAddTaskToReadyQueue( pxTCB );\r
+                       }\r
+               }\r
+       }\r
+\r
+#endif\r
+\r
+       \r
+\r
+       \r
 \r