]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Source/tasks.c
Core kernel code changes:
[freertos] / FreeRTOS / Source / tasks.c
index 3dcb0049e342140069cba1af7b5ee4eb7df926cc..4f2c29baded9276cc34bec0908d6f443182c14ad 100644 (file)
@@ -199,8 +199,12 @@ typedef struct tskTaskControlBlock
                volatile uint8_t ucNotifyState;\r
        #endif\r
 \r
-       #if ( configSUPPORT_STATIC_ALLOCATION == 1 )\r
-               uint8_t         ucStaticAllocationFlags; /* Set to pdTRUE if the stack is a statically allocated array, and pdFALSE if the stack is dynamically allocated. */\r
+       #if( configSUPPORT_STATIC_ALLOCATION == 1 )\r
+               uint8_t ucStaticAllocationFlags; /* Set to pdTRUE if the stack is a statically allocated array, and pdFALSE if the stack is dynamically allocated. */\r
+       #endif\r
+\r
+       #if( INCLUDE_xTaskAbortDelay == 1 )\r
+               uint8_t ucDelayAborted;\r
        #endif\r
 \r
 } tskTCB;\r
@@ -210,8 +214,8 @@ below to enable the use of older kernel aware debuggers. */
 typedef tskTCB TCB_t;\r
 \r
 /*\r
- * Some kernel aware debuggers require the data the debugger needs access to to\r
- * be global, rather than file scope.\r
+ * Some kernel aware debuggers require the data the debugger needs access to be\r
+ * global, rather than file scope.\r
  */\r
 #ifdef portREMOVE_STATIC_QUALIFIER\r
        #define static\r
@@ -1244,7 +1248,7 @@ StackType_t *pxTopOfStack;
                                        mtCOVERAGE_TEST_MARKER();\r
                                }\r
 \r
-                               if( xYieldRequired == pdTRUE )\r
+                               if( xYieldRequired != pdFALSE )\r
                                {\r
                                        taskYIELD_IF_USING_PREEMPTION();\r
                                }\r
@@ -1415,7 +1419,7 @@ StackType_t *pxTopOfStack;
                {\r
                        taskENTER_CRITICAL();\r
                        {\r
-                               if( prvTaskIsTaskSuspended( pxTCB ) == pdTRUE )\r
+                               if( prvTaskIsTaskSuspended( pxTCB ) != pdFALSE )\r
                                {\r
                                        traceTASK_RESUME( pxTCB );\r
 \r
@@ -1484,7 +1488,7 @@ StackType_t *pxTopOfStack;
 \r
                uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();\r
                {\r
-                       if( prvTaskIsTaskSuspended( pxTCB ) == pdTRUE )\r
+                       if( prvTaskIsTaskSuspended( pxTCB ) != pdFALSE )\r
                        {\r
                                traceTASK_RESUME_FROM_ISR( pxTCB );\r
 \r
@@ -1769,7 +1773,7 @@ BaseType_t xAlreadyYielded = pdFALSE;
                                        mtCOVERAGE_TEST_MARKER();\r
                                }\r
 \r
-                               if( xYieldPending == pdTRUE )\r
+                               if( xYieldPending != pdFALSE )\r
                                {\r
                                        #if( configUSE_PREEMPTION != 0 )\r
                                        {\r
@@ -1933,6 +1937,9 @@ UBaseType_t uxTaskGetNumberOfTasks( void )
        UBaseType_t uxQueue = configMAX_PRIORITIES;\r
        TCB_t* pxTCB;\r
 \r
+               /* Task names will be truncated to configMAX_TASK_NAME_LEN - 1 bytes. */\r
+               configASSERT( strlen( pcNameToQuery ) < configMAX_TASK_NAME_LEN );\r
+\r
                vTaskSuspendAll();\r
                {\r
                        /* Search the ready lists. */\r
@@ -2094,6 +2101,80 @@ implementations require configUSE_TICKLESS_IDLE to be set to a value other than
 #endif /* configUSE_TICKLESS_IDLE */\r
 /*----------------------------------------------------------*/\r
 \r
+#if ( INCLUDE_xTaskAbortDelay == 1 )\r
+\r
+       BaseType_t xTaskAbortDelay( TaskHandle_t xTask )\r
+       {\r
+       TCB_t *pxTCB = ( TCB_t * ) xTask;\r
+       BaseType_t xReturn = pdFALSE;\r
+\r
+               configASSERT( pxTCB );\r
+\r
+               vTaskSuspendAll();\r
+               {\r
+                       /* A task can only be prematurely removed from the Blocked state if\r
+                       it is actually in the Blocked state. */\r
+                       if( eTaskGetState( xTask ) == eBlocked )\r
+                       {\r
+                               /* Remove the reference to the task from the blocked list.  An\r
+                               interrupt won't touch the xGenericListItem because the\r
+                               scheduler is suspended. */\r
+                               ( void ) uxListRemove( &( pxTCB->xGenericListItem ) );\r
+\r
+                               /* Is the task waiting on an event also?  If so remove it from\r
+                               the event list too.  Interrupts can touch the event list item,\r
+                               even though the scheduler is suspended, so a critical section\r
+                               is used. */\r
+                               taskENTER_CRITICAL();\r
+                               {\r
+                                       if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )\r
+                                       {\r
+                                               ( void ) uxListRemove( &( pxTCB->xEventListItem ) );\r
+                                               pxTCB->ucDelayAborted = pdTRUE;\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               mtCOVERAGE_TEST_MARKER();\r
+                                       }\r
+                               }\r
+                               taskEXIT_CRITICAL();\r
+\r
+                               /* Place the unblocked task into the appropriate ready list. */\r
+                               prvAddTaskToReadyList( pxTCB );\r
+\r
+                               /* A task being unblocked cannot cause an immediate context\r
+                               switch if preemption is turned off. */\r
+                               #if (  configUSE_PREEMPTION == 1 )\r
+                               {\r
+                                       /* Preemption is on, but a context switch should only be\r
+                                       performed if the unblocked task has a priority that is\r
+                                       equal to or higher than the currently executing task. */\r
+                                       if( pxTCB->uxPriority > pxCurrentTCB->uxPriority )\r
+                                       {\r
+                                               /* Pend the yield to be performed when the scheduler\r
+                                               is unsuspended. */\r
+                                               xYieldPending = pdTRUE;\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               mtCOVERAGE_TEST_MARKER();\r
+                                       }\r
+                               }\r
+                               #endif /* configUSE_PREEMPTION */\r
+                       }\r
+                       else\r
+                       {\r
+                               mtCOVERAGE_TEST_MARKER();\r
+                       }\r
+               }\r
+               xTaskResumeAll();\r
+\r
+               return xReturn;\r
+       }\r
+\r
+#endif /* INCLUDE_xTaskAbortDelay */\r
+/*----------------------------------------------------------*/\r
+\r
 BaseType_t xTaskIncrementTick( void )\r
 {\r
 TCB_t * pxTCB;\r
@@ -2479,7 +2560,7 @@ void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, const TickType_t xIte
                /* If the task should block indefinitely then set the block time to a\r
                value that will be recognised as an indefinite delay inside the\r
                prvAddCurrentTaskToDelayedList() function. */\r
-               if( xWaitIndefinitely == pdTRUE )\r
+               if( xWaitIndefinitely != pdFALSE )\r
                {\r
                        xTicksToWait = portMAX_DELAY;\r
                }\r
@@ -2624,15 +2705,26 @@ BaseType_t xReturn;
                /* Minor optimisation.  The tick count cannot change in this block. */\r
                const TickType_t xConstTickCount = xTickCount;\r
 \r
+               #if( INCLUDE_xTaskAbortDelay == 1 )\r
+                       if( pxCurrentTCB->ucDelayAborted != pdFALSE )\r
+                       {\r
+                               /* The delay was aborted, which is not the same as a time out,\r
+                               but has the same result. */\r
+                               pxCurrentTCB->ucDelayAborted = pdFALSE;\r
+                               xReturn = pdTRUE;\r
+                       }\r
+                       else\r
+               #endif\r
+\r
                #if ( INCLUDE_vTaskSuspend == 1 )\r
-                       /* If INCLUDE_vTaskSuspend is set to 1 and the block time specified\r
-                       is the maximum block time then the task should block indefinitely,\r
-                       and therefore never time out. */\r
                        if( *pxTicksToWait == portMAX_DELAY )\r
                        {\r
+                               /* If INCLUDE_vTaskSuspend is set to 1 and the block time\r
+                               specified is the maximum block time then the task should block\r
+                               indefinitely, and therefore never time out. */\r
                                xReturn = pdFALSE;\r
                        }\r
-                       else /* We are not blocking indefinitely, perform the checks below. */\r
+                       else\r
                #endif\r
 \r
                if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( xConstTickCount >= pxTimeOut->xTimeOnEntering ) ) /*lint !e525 Indentation preferred as is to make code within pre-processor directives clearer. */\r
@@ -2644,7 +2736,7 @@ BaseType_t xReturn;
                        was called. */\r
                        xReturn = pdTRUE;\r
                }\r
-               else if( ( ( TickType_t ) ( xConstTickCount - pxTimeOut->xTimeOnEntering ) ) < *pxTicksToWait )\r
+               else if( ( ( TickType_t ) ( xConstTickCount - pxTimeOut->xTimeOnEntering ) ) < *pxTicksToWait ) /*lint !e961 Explicit casting is only redundant with some compilers, whereas others require it to prevent integer conversion errors. */\r
                {\r
                        /* Not a genuine timeout. Adjust parameters for time remaining. */\r
                        *pxTicksToWait -= ( xConstTickCount - pxTimeOut->xTimeOnEntering );\r
@@ -2971,6 +3063,12 @@ UBaseType_t x;
                _REENT_INIT_PTR( ( &( pxTCB->xNewLib_reent ) ) );\r
        }\r
        #endif\r
+\r
+       #if( INCLUDE_xTaskAbortDelay == 1 )\r
+       {\r
+               pxTCB->ucDelayAborted = pdFALSE;\r
+       }\r
+       #endif\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -4499,10 +4597,19 @@ TickType_t uxReturn;
 /*-----------------------------------------------------------*/\r
 \r
 \r
-static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, BaseType_t xCanBlockIndefinitely )\r
+static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, const BaseType_t xCanBlockIndefinitely )\r
 {\r
 TickType_t xTimeToWake;\r
 \r
+       #if( INCLUDE_xTaskAbortDelay == 1 )\r
+       {\r
+               /* About to enter a delayed list, so ensure the ucDelayAborted flag is\r
+               reset to pdFALSE so it can be detected as having been set to pdTRUE\r
+               when the task leaves the Blocked state. */\r
+               pxCurrentTCB->ucDelayAborted = pdFALSE;\r
+       }\r
+       #endif\r
+\r
        /* Remove the task from the ready list before adding it to the blocked list\r
        as the same list item is used for both lists. */\r
        if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )\r