/*\r
- FreeRTOS.org V4.1.0 - Copyright (C) 2003-2006 Richard Barry.\r
+ FreeRTOS.org V4.6.1 - Copyright (C) 2003-2007 Richard Barry.\r
\r
This file is part of the FreeRTOS.org distribution.\r
\r
See http://www.FreeRTOS.org for documentation, latest information, license\r
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 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
\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
+Changes since V4.3.1:\r
+\r
+ + Added xTaskGetSchedulerState() function.\r
+ + Added prvIsTaskSuspended() to take into account the Occurrence of\r
+ vTaskResume() or vTaskResumeFromISR() being called passing in the\r
+ handle of a task that appears in the Suspended list only because it\r
+ is blocked on an event without a timeout being specified.\r
+ + Updated xTaskCheckForTimeout() to take into account that tasks blocked\r
+ using the Suspended list should never time out.\r
*/\r
\r
#include <stdio.h>\r
#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
\r
#ifndef INCLUDE_xTaskResumeFromISR\r
#define INCLUDE_xTaskResumeFromISR 1\r
-#endif \r
+#endif\r
+\r
+#ifndef INCLUDE_xTaskGetSchedulerState\r
+ #define INCLUDE_xTaskGetSchedulerState 0\r
+#endif\r
\r
/*\r
* Task control block. A task control block (TCB) is allocated to each task,\r
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
* 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
*/\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
*/\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
+/*\r
+ * Checks that a task being resumed (unsuspended) is actually in the Suspended\r
+ * state.\r
+ */\r
+#if ( INCLUDE_vTaskSuspend == 1 )\r
+\r
+ static portBASE_TYPE prvIsTaskSuspended( const tskTCB * const pxTCB ); \r
\r
#endif\r
\r
{\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
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
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
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
\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
/* 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
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
#endif\r
/*-----------------------------------------------------------*/\r
\r
+#if ( INCLUDE_vTaskSuspend == 1 )\r
+\r
+ static portBASE_TYPE prvIsTaskSuspended( const tskTCB * const pxTCB )\r
+ {\r
+ portBASE_TYPE xReturn = pdFALSE;\r
+\r
+ /* Is the task we are attempting to resume actually in the\r
+ suspended list? */\r
+ if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE )\r
+ {\r
+ /* Has the task already been resumed from within an ISR? */\r
+ if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE )\r
+ { \r
+ /* Is it in the suspended list because it is in the\r
+ Suspended state? It is possible to be in the suspended\r
+ list because it is blocked on a task with no timeout\r
+ specified. */\r
+ if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) == pdTRUE )\r
+ {\r
+ xReturn = pdTRUE;\r
+ }\r
+ }\r
+ }\r
+\r
+ return xReturn;\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
#if ( INCLUDE_vTaskSuspend == 1 )\r
\r
void vTaskResume( xTaskHandle pxTaskToResume )\r
{\r
taskENTER_CRITICAL();\r
{\r
- /* Is the task we are attempting to resume actually suspended? */\r
- if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE )\r
+ if( prvIsTaskSuspended( pxTCB ) == pdTRUE )\r
{\r
- /* Has the task already been resumed from within an ISR? */\r
- if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE )\r
- { \r
- /* As we are in a critical section we can access the ready \r
- lists even if the scheduler is suspended. */\r
- vListRemove( &( pxTCB->xGenericListItem ) );\r
- prvAddTaskToReadyQueue( pxTCB );\r
-\r
- /* We may have just resumed a higher priority task. */\r
- if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )\r
- {\r
- /* This yield may not cause the task just resumed to run, but\r
- will leave the lists in the correct state for the next yield. */\r
- taskYIELD();\r
- }\r
+ /* As we are in a critical section we can access the ready\r
+ lists even if the scheduler is suspended. */\r
+ vListRemove( &( pxTCB->xGenericListItem ) );\r
+ prvAddTaskToReadyQueue( pxTCB );\r
+\r
+ /* We may have just resumed a higher priority task. */\r
+ if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )\r
+ {\r
+ /* This yield may not cause the task just resumed to run, but\r
+ will leave the lists in the correct state for the next yield. */\r
+ taskYIELD();\r
}\r
}\r
}\r
\r
pxTCB = ( tskTCB * ) pxTaskToResume;\r
\r
- /* Is the task we are attempting to resume actually suspended? */\r
- if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE )\r
+ if( prvIsTaskSuspended( pxTCB ) == pdTRUE )\r
{\r
- /* Has the task already been resumed from within an ISR? */\r
- if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE )\r
+ if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
{\r
- if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
- {\r
- xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority );\r
- vListRemove( &( pxTCB->xGenericListItem ) ); \r
- prvAddTaskToReadyQueue( pxTCB );\r
- }\r
- else\r
- {\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
- vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxTCB->xEventListItem ) );\r
- }\r
+ xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority );\r
+ vListRemove( &( pxTCB->xGenericListItem ) ); \r
+ prvAddTaskToReadyQueue( pxTCB );\r
+ }\r
+ else\r
+ {\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 performed if necessary. */\r
+ vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxTCB->xEventListItem ) );\r
}\r
}\r
\r
\r
prvDeleteTCB( ( tskTCB * ) pxTCB );\r
} \r
-\r
- while( !listLIST_IS_EMPTY( &xPendingReadyList ) )\r
- {\r
- listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &xPendingReadyList );\r
- vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) );\r
-\r
- prvDeleteTCB( ( tskTCB * ) pxTCB );\r
- } \r
}\r
\r
#endif\r
}\r
/*-----------------------------------------------------------*/\r
\r
-void vTaskPlaceOnEventList( xList *pxEventList, portTickType xTicksToWait )\r
+void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait )\r
{\r
portTickType xTimeToWake;\r
\r
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
-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
}\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 *pxTicksToWait )\r
+portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait )\r
{\r
portBASE_TYPE xReturn;\r
\r
- if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( xTickCount > pxTimeOut->xTimeOnEntering ) )\r
+ #if ( INCLUDE_vTaskSuspend == 1 )\r
+ /* If INCLUDE_vTaskSuspend is set to 1 and the block time specified is\r
+ the maximum block time then the task should block indefinitely, and\r
+ therefore never time out. */\r
+ if( *pxTicksToWait == portMAX_DELAY )\r
+ {\r
+ xReturn = pdFALSE;\r
+ }\r
+ else /* We are not blocking indefinitely, perform the checks below. */\r
+ #endif\r
+\r
+ if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( xTickCount >= pxTimeOut->xTimeOnEntering ) )\r
{\r
- /* The tick count is greater than the time at which vTaskSetTimeout() \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
\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
}\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
\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
/*-----------------------------------------------------------*/\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
\r
#endif\r
\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( INCLUDE_xTaskGetSchedulerState == 1 )\r
+\r
+ portBASE_TYPE xTaskGetSchedulerState( void )\r
+ {\r
+ portBASE_TYPE xReturn;\r
+ \r
+ if( xSchedulerRunning == pdFALSE )\r
+ {\r
+ xReturn = taskSCHEDULER_NOT_STARTED;\r
+ }\r
+ else\r
+ {\r
+ if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
+ {\r
+ xReturn = taskSCHEDULER_RUNNING;\r
+ }\r
+ else\r
+ {\r
+ xReturn = taskSCHEDULER_SUSPENDED;\r
+ }\r
+ }\r
+ \r
+ return xReturn;\r
+ }\r
+\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