]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Source/tasks.c
Kernel code:
[freertos] / FreeRTOS / Source / tasks.c
index e7274dbc63ad67c857d2a70130f4828a16ba2f3d..822338df1d1f4117fbaf5ed50b15fc1d2ac4cfde 100644 (file)
@@ -168,6 +168,10 @@ typedef struct tskTaskControlBlock
                TaskHookFunction_t pxTaskTag;\r
        #endif\r
 \r
+       #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )\r
+               void *pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];\r
+       #endif\r
+\r
        #if ( configGENERATE_RUN_TIME_STATS == 1 )\r
                uint32_t                ulRunTimeCounter;       /*< Stores the amount of time the task has spent in the Running state. */\r
        #endif\r
@@ -383,7 +387,7 @@ count overflows. */
  * the task.  It is inserted at the end of the list.\r
  */\r
 #define prvAddTaskToReadyList( pxTCB )                                                                                                                         \\r
-       traceMOVED_TASK_TO_READY_STATE( pxTCB )                                                                                                                 \\r
+       traceMOVED_TASK_TO_READY_STATE( pxTCB );                                                                                                                \\r
        taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority );                                                                                             \\r
        vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xGenericListItem ) )\r
 /*-----------------------------------------------------------*/\r
@@ -594,7 +598,7 @@ StackType_t *pxTopOfStack;
                #if( portSTACK_GROWTH < 0 )\r
                {\r
                        pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - ( uint16_t ) 1 );\r
-                       pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK  ) ); /*lint !e923 MISRA exception.  Avoiding casts between pointers and integers is not practical.  Size differences accounted for using portPOINTER_SIZE_TYPE type. */\r
+                       pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); /*lint !e923 MISRA exception.  Avoiding casts between pointers and integers is not practical.  Size differences accounted for using portPOINTER_SIZE_TYPE type. */\r
 \r
                        /* Check the alignment of the calculated top of stack is correct. */\r
                        configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );\r
@@ -2391,7 +2395,7 @@ TickType_t xTimeToWake;
                /* This function should not be called by application code hence the\r
                'Restricted' in its name.  It is not part of the public API.  It is\r
                designed for use by kernel code, and has special calling requirements -\r
-               it should be called from a critical section. */\r
+               it should be called with the scheduler suspended. */\r
 \r
 \r
                /* Place the event list item of the TCB in the appropriate event list.\r
@@ -2402,7 +2406,8 @@ TickType_t xTimeToWake;
 \r
                /* We must remove this task from the ready list before adding it to the\r
                blocked list as the same list item is used for both lists.  This\r
-               function is called form a critical section. */\r
+               function is called with the scheduler locked so interrupts will not\r
+               access the lists at the same time. */\r
                if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )\r
                {\r
                        /* The current task must be in a ready list, so there is no need to\r
@@ -2882,6 +2887,15 @@ UBaseType_t x;
        }\r
        #endif /* portUSING_MPU_WRAPPERS */\r
 \r
+       #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 )\r
+       {\r
+               for( x = 0; x < ( UBaseType_t ) configNUM_THREAD_LOCAL_STORAGE_POINTERS; x++ )\r
+               {\r
+                       pxTCB->pvThreadLocalStoragePointers[ x ] = NULL;\r
+               }\r
+       }\r
+       #endif\r
+\r
        #if ( configUSE_TASK_NOTIFICATIONS == 1 )\r
        {\r
                pxTCB->ulNotifiedValue = 0;\r
@@ -2898,6 +2912,45 @@ UBaseType_t x;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 )\r
+\r
+       void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue )\r
+       {\r
+       TCB_t *pxTCB;\r
+\r
+               if( xIndex < configNUM_THREAD_LOCAL_STORAGE_POINTERS )\r
+               {\r
+                       pxTCB = prvGetTCBFromHandle( xTaskToSet );\r
+                       pxTCB->pvThreadLocalStoragePointers[ xIndex ] = pvValue;\r
+               }\r
+       }\r
+\r
+#endif /* configNUM_THREAD_LOCAL_STORAGE_POINTERS */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 )\r
+\r
+       void *pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex )\r
+       {\r
+       void *pvReturn = NULL;\r
+       TCB_t *pxTCB;\r
+\r
+               if( xIndex < configNUM_THREAD_LOCAL_STORAGE_POINTERS )\r
+               {\r
+                       pxTCB = prvGetTCBFromHandle( xTaskToQuery );\r
+                       pvReturn = pxTCB->pvThreadLocalStoragePointers[ xIndex ];\r
+               }\r
+               else\r
+               {\r
+                       pvReturn = NULL;\r
+               }\r
+\r
+               return pvReturn;\r
+       }\r
+\r
+#endif /* configNUM_THREAD_LOCAL_STORAGE_POINTERS */\r
+/*-----------------------------------------------------------*/\r
+\r
 #if ( portUSING_MPU_WRAPPERS == 1 )\r
 \r
        void vTaskAllocateMPURegions( TaskHandle_t xTaskToModify, const MemoryRegion_t * const xRegions )\r
@@ -3268,9 +3321,8 @@ TCB_t *pxTCB;
 \r
        if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE )\r
        {\r
-               /* The new current delayed list is empty.  Set\r
-               xNextTaskUnblockTime to the maximum possible value so it is\r
-               extremely unlikely that the\r
+               /* The new current delayed list is empty.  Set xNextTaskUnblockTime to\r
+               the maximum possible value so it is     extremely unlikely that the\r
                if( xTickCount >= xNextTaskUnblockTime ) test will pass until\r
                there is an item in the delayed list. */\r
                xNextTaskUnblockTime = portMAX_DELAY;\r
@@ -3342,6 +3394,9 @@ TCB_t *pxTCB;
                locked then the mutex holder might now be NULL. */\r
                if( pxMutexHolder != NULL )\r
                {\r
+                       /* If the holder of the mutex has a priority below the priority of\r
+                       the task attempting to obtain the mutex then it will temporarily\r
+                       inherit the priority of the task attempting to obtain the mutex. */\r
                        if( pxTCB->uxPriority < pxCurrentTCB->uxPriority )\r
                        {\r
                                /* Adjust the mutex holder state to account for its new\r
@@ -3356,8 +3411,8 @@ TCB_t *pxTCB;
                                        mtCOVERAGE_TEST_MARKER();\r
                                }\r
 \r
-                               /* If the task being modified is in the ready state it will need to\r
-                               be moved into a new list. */\r
+                               /* If the task being modified is in the ready state it will need\r
+                               to be moved into a new list. */\r
                                if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ) != pdFALSE )\r
                                {\r
                                        if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )\r
@@ -3404,15 +3459,23 @@ TCB_t *pxTCB;
 \r
                if( pxMutexHolder != NULL )\r
                {\r
+                       /* A task can only have an inherited priority if it holds the mutex.\r
+                       If the mutex is held by a task then it cannot be given from an\r
+                       interrupt, and if a mutex is given by the holding task then it must\r
+                       be the running state task. */\r
+                       configASSERT( pxTCB == pxCurrentTCB );\r
+\r
                        configASSERT( pxTCB->uxMutexesHeld );\r
                        ( pxTCB->uxMutexesHeld )--;\r
 \r
+                       /* Has the holder of the mutex inherited the priority of another\r
+                       task? */\r
                        if( pxTCB->uxPriority != pxTCB->uxBasePriority )\r
                        {\r
                                /* Only disinherit if no other mutexes are held. */\r
                                if( pxTCB->uxMutexesHeld == ( UBaseType_t ) 0 )\r
                                {\r
-                                       /* A task can only have an inhertied priority if it holds\r
+                                       /* A task can only have an inherited priority if it holds\r
                                        the mutex.  If the mutex is held by a task then it cannot be\r
                                        given from an interrupt, and if a mutex is given by the\r
                                        holding task then it must be the running state task.  Remove\r
@@ -4100,7 +4163,7 @@ TickType_t uxReturn;
                                {\r
                                        /* The notified task has a priority above the currently\r
                                        executing task so a yield is required. */\r
-                                       portYIELD_WITHIN_API();\r
+                                       taskYIELD_IF_USING_PREEMPTION();\r
                                }\r
                                else\r
                                {\r