]> git.sur5r.net Git - freertos/commitdiff
Introduced configUSE_PORT_OPTIMISED_TASK_SELECTION, and updated the MSVC simulator...
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Sun, 23 Sep 2012 14:35:12 +0000 (14:35 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Sun, 23 Sep 2012 14:35:12 +0000 (14:35 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1781 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

FreeRTOS/Demo/WIN32-MSVC/FreeRTOSConfig.h
FreeRTOS/Source/include/FreeRTOS.h
FreeRTOS/Source/portable/MSVC-MingW/portmacro.h
FreeRTOS/Source/tasks.c

index 77e9362e8c0a1590994712a7541d9382cd0161d9..c03e2b29ccc5d56892318ed89be80b6c381685d1 100644 (file)
 #define configTIMER_QUEUE_LENGTH               20\r
 #define configTIMER_TASK_STACK_DEPTH   ( configMINIMAL_STACK_SIZE * 2 )\r
 \r
-#define configMAX_PRIORITIES                   ( ( unsigned portBASE_TYPE ) 7 )\r
+#define configMAX_PRIORITIES                   ( 7 )\r
 #define configMAX_CO_ROUTINE_PRIORITIES ( 2 )\r
 \r
 \r
@@ -132,4 +132,9 @@ to exclude the API function. */
 extern void vAssertCalled( void );\r
 #define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled()\r
 \r
+/* configUSE_PORT_OPTIMISED_TASK_SELECTION is only available in the MSVC \r
+version of the Win32 simulator projects.  It will be ignored in the GCC\r
+version. */\r
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1\r
+\r
 #endif /* FREERTOS_CONFIG_H */\r
index 17c5c682d201767b1ce08f7c62bd1326634a1bd6..ab58749bed83690387ca29003f9cf4cd1f2e0cb2 100644 (file)
@@ -165,6 +165,10 @@ typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * );
        #define INCLUDE_uxTaskGetStackHighWaterMark 0\r
 #endif\r
 \r
+#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION\r
+       #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0\r
+#endif\r
+\r
 #ifndef INCLUDE_cTaskStateGet\r
        #define INCLUDE_cTaskStateGet 0\r
 #endif\r
index 484aac5d20e46ae44c18d786268207b740ec30e1..9a991ab6f57541af687803b5d6fc8780a0082cfa 100644 (file)
@@ -108,6 +108,30 @@ void vPortExitCritical( void );
 #define portENTER_CRITICAL()           vPortEnterCritical()\r
 #define portEXIT_CRITICAL()                    vPortExitCritical()\r
 \r
+#ifndef __GNUC__\r
+       #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1\r
+\r
+       /* Check the configuration. */\r
+       #if( configMAX_PRIORITIES >= 32 )\r
+               #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32.  It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.\r
+       #endif\r
+\r
+               /* Store/clear the ready priorities in a bit map. */\r
+               #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )\r
+               #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )\r
+\r
+\r
+               /*-----------------------------------------------------------*/\r
+\r
+               /* BitScanReverse returns the bit position of the most significant '1'\r
+               in the word. */\r
+               #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) _BitScanReverse( ( DWORD * ) &( uxTopPriority ), ( uxReadyPriorities ) )\r
+\r
+       #endif /* taskRECORD_READY_PRIORITY */\r
+#endif /* __GNUC__ */\r
+\r
+\r
+\r
 /* Task function macros as described on the FreeRTOS.org WEB site. */\r
 #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )\r
 #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )\r
index 8d622939babf8baca1649b52d0c580a1fdff00fe..9e0649a21900246335212d44954a466b968fd959 100644 (file)
@@ -210,6 +210,72 @@ PRIVILEGED_DATA static portTickType xNextTaskUnblockTime                                           = ( portTickType )
 \r
 /*-----------------------------------------------------------*/\r
 \r
+#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 0\r
+       /* \r
+        * uxTopReadyPriority holds the priority of the highest priority ready\r
+        * state task.\r
+        */\r
+       #define taskRECORD_READY_PRIORITY( uxPriority )                                                                                                                                         \\r
+       {                                                                                                                                                                                                                                       \\r
+               if( ( uxPriority ) > uxTopReadyPriority )                                                                                                                                               \\r
+               {                                                                                                                                                                                                                               \\r
+                       uxTopReadyPriority = ( uxPriority );                                                                                                                                            \\r
+               }                                                                                                                                                                                                                               \\r
+       } /* taskRECORD_READY_PRIORITY */\r
+\r
+       /*-----------------------------------------------------------*/\r
+\r
+       #define taskSELECT_HIGHEST_PRIORITY_TASK()                                                                                                                                                      \\r
+       {                                                                                                                                                                                                                                       \\r
+               /* Find the highest priority queue that contains ready tasks. */                                                                                                \\r
+               while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) )                                                                              \\r
+               {                                                                                                                                                                                                                               \\r
+                       configASSERT( uxTopReadyPriority );                                                                                                                                                     \\r
+                       --uxTopReadyPriority;                                                                                                                                                                           \\r
+               }                                                                                                                                                                                                                               \\r
+                                                                                                                                                                                                                                               \\r
+               /* listGET_OWNER_OF_NEXT_ENTRY indexes through the list, so the tasks of                                                                                \\r
+               the     same priority get an equal share of the processor time. */                                                                                                      \\r
+               listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) );                                              \\r
+       } /* taskSELECT_HIGHEST_PRIORITY_TASK */\r
+\r
+       /*-----------------------------------------------------------*/\r
+\r
+       /* Define away taskCHECK_READY_LIST() as it is not required in this\r
+       configuration. */\r
+       #define taskCHECK_READY_LIST( uxPriority )\r
+\r
+#else /* configUSE_PORT_OPTIMISED_TASK_SELECTION */\r
+\r
+       /* A port optimised version is provided.  Call the port defined macros. */\r
+       #define taskRECORD_READY_PRIORITY( uxPriority ) portRECORD_READY_PRIORITY( uxPriority, uxTopReadyPriority )\r
+\r
+       /*-----------------------------------------------------------*/\r
+\r
+       #define taskSELECT_HIGHEST_PRIORITY_TASK()                                                                                                                                                      \\r
+       {                                                                                                                                                                                                                                       \\r
+       unsigned portBASE_TYPE uxTopPriority;                                                                                                                                                           \\r
+                                                                                                                                                                                                                                               \\r
+               /* Find the highest priority queue that contains ready tasks. */                                                                                                \\r
+               portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority );                                                                                                  \\r
+               listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) );                                                   \\r
+       } /* taskSELECT_HIGHEST_PRIORITY_TASK() */\r
+\r
+       /*-----------------------------------------------------------*/\r
+\r
+       /* Let the port layer know if the ready list is empty so \r
+       taskSELECT_HIGHEST_PRIORITY_TASK() can function correctly. */\r
+       #define taskCHECK_READY_LIST( uxPriority )                                                                                                                                                      \\r
+       {                                                                                                                                                                                                                                       \\r
+               if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ ( uxPriority ) ] ) ) == 0 )                                                                  \\r
+               {                                                                                                                                                                                                                               \\r
+                       portRESET_READY_PRIORITY( ( uxPriority ), uxTopReadyPriority );                                                                                         \\r
+               }                                                                                                                                                                                                                               \\r
+       } /* taskCHECK_READY_LIST() */\r
+\r
+\r
+#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */\r
+\r
 /*\r
  * Place the task represented by pxTCB into the appropriate ready queue for\r
  * the task.  It is inserted at the end of the list.  One quirk of this is\r
@@ -219,10 +285,7 @@ PRIVILEGED_DATA static portTickType xNextTaskUnblockTime                                           = ( portTickType )
  */\r
 #define prvAddTaskToReadyQueue( pxTCB )                                                                                                                                                                        \\r
        traceMOVED_TASK_TO_READY_STATE( pxTCB )                                                                                                                                                         \\r
-       if( ( pxTCB )->uxPriority > uxTopReadyPriority )                                                                                                                                        \\r
-       {                                                                                                                                                                                                                                       \\r
-               uxTopReadyPriority = ( pxTCB )->uxPriority;                                                                                                                                             \\r
-       }                                                                                                                                                                                                                                       \\r
+       taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority );                                                                                                                                     \\r
        vListInsertEnd( ( xList * ) &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xGenericListItem ) )\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -579,6 +642,7 @@ tskTCB * pxNewTCB;
                        the termination list and free up any memory allocated by the\r
                        scheduler for the TCB and stack. */\r
                        vListRemove( &( pxTCB->xGenericListItem ) );\r
+                       taskCHECK_READY_LIST( pxTCB->uxPriority );\r
 \r
                        /* Is the task waiting on an event also? */\r
                        if( pxTCB->xEventListItem.pvContainer != NULL )\r
@@ -671,6 +735,7 @@ tskTCB * pxNewTCB;
                                ourselves to the blocked list as the same list item is used for\r
                                both lists. */\r
                                vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
+                               taskCHECK_READY_LIST( pxCurrentTCB->uxPriority );\r
                                prvAddCurrentTaskToDelayedList( xTimeToWake );\r
                        }\r
                }\r
@@ -717,6 +782,7 @@ tskTCB * pxNewTCB;
                                ourselves to the blocked list as the same list item is used for\r
                                both lists. */\r
                                vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
+                               taskCHECK_READY_LIST( pxCurrentTCB->uxPriority );\r
                                prvAddCurrentTaskToDelayedList( xTimeToWake );\r
                        }\r
                        xAlreadyYielded = xTaskResumeAll();\r
@@ -910,6 +976,7 @@ tskTCB * pxNewTCB;
                                        it to it's new ready list.  As we are in a critical section we\r
                                        can do this even if the scheduler is suspended. */\r
                                        vListRemove( &( pxTCB->xGenericListItem ) );\r
+                                       taskCHECK_READY_LIST( uxCurrentPriority );\r
                                        prvAddTaskToReadyQueue( pxTCB );\r
                                }\r
 \r
@@ -947,6 +1014,7 @@ tskTCB * pxNewTCB;
 \r
                        /* Remove task from the ready/delayed list and place in the     suspended list. */\r
                        vListRemove( &( pxTCB->xGenericListItem ) );\r
+                       taskCHECK_READY_LIST( pxTCB->uxPriority );\r
 \r
                        /* Is the task waiting on an event also? */\r
                        if( pxTCB->xEventListItem.pvContainer != NULL )\r
@@ -1690,17 +1758,8 @@ void vTaskSwitchContext( void )
                taskFIRST_CHECK_FOR_STACK_OVERFLOW();\r
                taskSECOND_CHECK_FOR_STACK_OVERFLOW();\r
        \r
-               /* Find the highest priority queue that contains ready tasks. */\r
-               while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) )\r
-               {\r
-                       configASSERT( uxTopReadyPriority );\r
-                       --uxTopReadyPriority;\r
-               }\r
-       \r
-               /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the tasks of the\r
-               same priority get an equal share of the processor time. */\r
-               listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) );\r
-       \r
+               taskSELECT_HIGHEST_PRIORITY_TASK();\r
+                       \r
                traceTASK_SWITCHED_IN();\r
        }\r
 }\r
@@ -1724,7 +1783,7 @@ portTickType xTimeToWake;
        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
+       taskCHECK_READY_LIST( pxCurrentTCB->uxPriority );\r
 \r
        #if ( INCLUDE_vTaskSuspend == 1 )\r
        {\r
@@ -1778,6 +1837,7 @@ portTickType xTimeToWake;
                blocked list as the same list item is used for both lists.  This\r
                function is called form a critical section. */\r
                vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
+               taskCHECK_READY_LIST( pxCurrentTCB->uxPriority );\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
@@ -2458,6 +2518,7 @@ tskTCB *pxNewTCB;
                                if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ) != pdFALSE )\r
                                {\r
                                        vListRemove( &( pxTCB->xGenericListItem ) );\r
+                                       taskCHECK_READY_LIST( pxTCB->uxPriority );\r
 \r
                                        /* Inherit the priority before being moved into the new list. */\r
                                        pxTCB->uxPriority = pxCurrentTCB->uxPriority;\r
@@ -2490,6 +2551,7 @@ tskTCB *pxNewTCB;
                                /* 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
+                               taskCHECK_READY_LIST( pxTCB->uxPriority );\r
 \r
                                /* Disinherit the priority before adding the task into the new\r
                                ready list. */\r