\r
#if ( configUSE_MUTEXES == 1 )\r
UBaseType_t uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */\r
+ UBaseType_t uxMutexesHeld;\r
#endif\r
\r
#if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
#if ( configUSE_MUTEXES == 1 )\r
{\r
pxTCB->uxBasePriority = uxPriority;\r
+ pxTCB->uxMutexesHeld = 0;\r
}\r
#endif /* configUSE_MUTEXES */\r
\r
\r
#if ( configUSE_MUTEXES == 1 )\r
\r
- void vTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder )\r
+ BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder )\r
{\r
TCB_t * const pxTCB = ( TCB_t * ) pxMutexHolder;\r
+ BaseType_t xReturn = pdFALSE;\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
- if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )\r
+ /* Only disinherit if no other mutexes are held. */\r
+ if( pxTCB->uxMutexesHeld == 0 )\r
{\r
- taskRESET_READY_PRIORITY( pxTCB->uxPriority );\r
- }\r
- else\r
- {\r
- mtCOVERAGE_TEST_MARKER();\r
- }\r
+ /* The holding task must be the running task to be able to give\r
+ the mutex back. Remove the holding task from the ready list. */\r
+ if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )\r
+ {\r
+ taskRESET_READY_PRIORITY( pxTCB->uxPriority );\r
+ }\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
\r
- /* Disinherit the priority before adding the task into the new\r
- ready list. */\r
- traceTASK_PRIORITY_DISINHERIT( pxTCB, pxTCB->uxBasePriority );\r
- pxTCB->uxPriority = pxTCB->uxBasePriority;\r
+ /* Disinherit the priority before adding the task into the new\r
+ ready list. */\r
+ traceTASK_PRIORITY_DISINHERIT( pxTCB, pxTCB->uxBasePriority );\r
+ pxTCB->uxPriority = pxTCB->uxBasePriority;\r
\r
- /* Only reset the event list item value if the value is not\r
- being used for anything else. */\r
- if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL )\r
- {\r
- listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */\r
+ /* Only reset the event list item value if the value is not\r
+ being used for anything else. */\r
+ if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL )\r
+ {\r
+ listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */\r
+ }\r
+ else\r
+ {\r
+#warning Is it possible to come through here?\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
+ prvAddTaskToReadyList( pxTCB );\r
+\r
+ /* Return true to indicate that a context switch is required.\r
+ This is only actually required in the corner case whereby\r
+ multiple mutexes were held and the mutexes were given back\r
+ in an order different to that in which they were taken. */\r
+ xReturn = pdTRUE;\r
}\r
else\r
{\r
mtCOVERAGE_TEST_MARKER();\r
}\r
- prvAddTaskToReadyList( pxTCB );\r
}\r
else\r
{\r
{\r
mtCOVERAGE_TEST_MARKER();\r
}\r
+\r
+ return xReturn;\r
}\r
\r
#endif /* configUSE_MUTEXES */\r
if( xSchedulerRunning != pdFALSE )\r
{\r
( pxCurrentTCB->uxCriticalNesting )++;\r
+\r
+ /* This is not the interrupt safe version of the enter critical\r
+ function so assert() if it is being called from an interrupt\r
+ context. Only API functions that end in "FromISR" can be used in an\r
+ interrupt. Only assert if the critical nesting count is 1 to\r
+ protect against recursive calls if the assert function also uses a\r
+ critical section. */\r
+ if( pxCurrentTCB->uxCriticalNesting == 1 )\r
+ {\r
+ portASSERT_IF_IN_ISR();\r
+ }\r
+\r
}\r
else\r
{\r
}\r
/*-----------------------------------------------------------*/\r
\r
+void vTaskIncrementMutexHeldCount( void )\r
+{\r
+ ( pxCurrentTCB->uxMutexesHeld )++;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vTaskDecrementMutexHeldCount( void )\r
+{\r
+ configASSERT( pxCurrentTCB->uxMutexesHeld );\r
+ ( pxCurrentTCB->uxMutexesHeld )--;\r
+}\r
+\r
#ifdef FREERTOS_MODULE_TEST\r
#include "tasks_test_access_functions.h"\r
#endif\r