mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Introduced configUSE_PORT_OPTIMISED_TASK_SELECTION, and updated the MSVC simulator port as the first implementation.
This commit is contained in:
parent
8ef7f03536
commit
670d172cfc
|
@ -104,7 +104,7 @@
|
|||
#define configTIMER_QUEUE_LENGTH 20
|
||||
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
|
||||
|
||||
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 7 )
|
||||
#define configMAX_PRIORITIES ( 7 )
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
||||
|
||||
|
||||
|
@ -132,4 +132,9 @@ to exclude the API function. */
|
|||
extern void vAssertCalled( void );
|
||||
#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled()
|
||||
|
||||
/* configUSE_PORT_OPTIMISED_TASK_SELECTION is only available in the MSVC
|
||||
version of the Win32 simulator projects. It will be ignored in the GCC
|
||||
version. */
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
|
||||
#endif /* FREERTOS_CONFIG_H */
|
||||
|
|
|
@ -165,6 +165,10 @@ typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * );
|
|||
#define INCLUDE_uxTaskGetStackHighWaterMark 0
|
||||
#endif
|
||||
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_cTaskStateGet
|
||||
#define INCLUDE_cTaskStateGet 0
|
||||
#endif
|
||||
|
|
|
@ -108,6 +108,30 @@ void vPortExitCritical( void );
|
|||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
|
||||
#ifndef __GNUC__
|
||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||
|
||||
/* Check the configuration. */
|
||||
#if( configMAX_PRIORITIES >= 32 )
|
||||
#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.
|
||||
#endif
|
||||
|
||||
/* Store/clear the ready priorities in a bit map. */
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* BitScanReverse returns the bit position of the most significant '1'
|
||||
in the word. */
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) _BitScanReverse( ( DWORD * ) &( uxTopPriority ), ( uxReadyPriorities ) )
|
||||
|
||||
#endif /* taskRECORD_READY_PRIORITY */
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
|
|
|
@ -210,6 +210,72 @@ PRIVILEGED_DATA static portTickType xNextTaskUnblockTime = ( portTickType )
|
|||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 0
|
||||
/*
|
||||
* uxTopReadyPriority holds the priority of the highest priority ready
|
||||
* state task.
|
||||
*/
|
||||
#define taskRECORD_READY_PRIORITY( uxPriority ) \
|
||||
{ \
|
||||
if( ( uxPriority ) > uxTopReadyPriority ) \
|
||||
{ \
|
||||
uxTopReadyPriority = ( uxPriority ); \
|
||||
} \
|
||||
} /* taskRECORD_READY_PRIORITY */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define taskSELECT_HIGHEST_PRIORITY_TASK() \
|
||||
{ \
|
||||
/* Find the highest priority queue that contains ready tasks. */ \
|
||||
while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) ) \
|
||||
{ \
|
||||
configASSERT( uxTopReadyPriority ); \
|
||||
--uxTopReadyPriority; \
|
||||
} \
|
||||
\
|
||||
/* listGET_OWNER_OF_NEXT_ENTRY indexes through the list, so the tasks of \
|
||||
the same priority get an equal share of the processor time. */ \
|
||||
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) ); \
|
||||
} /* taskSELECT_HIGHEST_PRIORITY_TASK */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Define away taskCHECK_READY_LIST() as it is not required in this
|
||||
configuration. */
|
||||
#define taskCHECK_READY_LIST( uxPriority )
|
||||
|
||||
#else /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
/* A port optimised version is provided. Call the port defined macros. */
|
||||
#define taskRECORD_READY_PRIORITY( uxPriority ) portRECORD_READY_PRIORITY( uxPriority, uxTopReadyPriority )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define taskSELECT_HIGHEST_PRIORITY_TASK() \
|
||||
{ \
|
||||
unsigned portBASE_TYPE uxTopPriority; \
|
||||
\
|
||||
/* Find the highest priority queue that contains ready tasks. */ \
|
||||
portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority ); \
|
||||
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \
|
||||
} /* taskSELECT_HIGHEST_PRIORITY_TASK() */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Let the port layer know if the ready list is empty so
|
||||
taskSELECT_HIGHEST_PRIORITY_TASK() can function correctly. */
|
||||
#define taskCHECK_READY_LIST( uxPriority ) \
|
||||
{ \
|
||||
if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ ( uxPriority ) ] ) ) == 0 ) \
|
||||
{ \
|
||||
portRESET_READY_PRIORITY( ( uxPriority ), uxTopReadyPriority ); \
|
||||
} \
|
||||
} /* taskCHECK_READY_LIST() */
|
||||
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
/*
|
||||
* Place the task represented by pxTCB into the appropriate ready queue for
|
||||
* the task. It is inserted at the end of the list. One quirk of this is
|
||||
|
@ -219,10 +285,7 @@ PRIVILEGED_DATA static portTickType xNextTaskUnblockTime = ( portTickType )
|
|||
*/
|
||||
#define prvAddTaskToReadyQueue( pxTCB ) \
|
||||
traceMOVED_TASK_TO_READY_STATE( pxTCB ) \
|
||||
if( ( pxTCB )->uxPriority > uxTopReadyPriority ) \
|
||||
{ \
|
||||
uxTopReadyPriority = ( pxTCB )->uxPriority; \
|
||||
} \
|
||||
taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority ); \
|
||||
vListInsertEnd( ( xList * ) &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xGenericListItem ) )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -579,6 +642,7 @@ tskTCB * pxNewTCB;
|
|||
the termination list and free up any memory allocated by the
|
||||
scheduler for the TCB and stack. */
|
||||
vListRemove( &( pxTCB->xGenericListItem ) );
|
||||
taskCHECK_READY_LIST( pxTCB->uxPriority );
|
||||
|
||||
/* Is the task waiting on an event also? */
|
||||
if( pxTCB->xEventListItem.pvContainer != NULL )
|
||||
|
@ -671,6 +735,7 @@ tskTCB * pxNewTCB;
|
|||
ourselves to the blocked list as the same list item is used for
|
||||
both lists. */
|
||||
vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
|
||||
taskCHECK_READY_LIST( pxCurrentTCB->uxPriority );
|
||||
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||
}
|
||||
}
|
||||
|
@ -717,6 +782,7 @@ tskTCB * pxNewTCB;
|
|||
ourselves to the blocked list as the same list item is used for
|
||||
both lists. */
|
||||
vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
|
||||
taskCHECK_READY_LIST( pxCurrentTCB->uxPriority );
|
||||
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||
}
|
||||
xAlreadyYielded = xTaskResumeAll();
|
||||
|
@ -910,6 +976,7 @@ tskTCB * pxNewTCB;
|
|||
it to it's new ready list. As we are in a critical section we
|
||||
can do this even if the scheduler is suspended. */
|
||||
vListRemove( &( pxTCB->xGenericListItem ) );
|
||||
taskCHECK_READY_LIST( uxCurrentPriority );
|
||||
prvAddTaskToReadyQueue( pxTCB );
|
||||
}
|
||||
|
||||
|
@ -947,6 +1014,7 @@ tskTCB * pxNewTCB;
|
|||
|
||||
/* Remove task from the ready/delayed list and place in the suspended list. */
|
||||
vListRemove( &( pxTCB->xGenericListItem ) );
|
||||
taskCHECK_READY_LIST( pxTCB->uxPriority );
|
||||
|
||||
/* Is the task waiting on an event also? */
|
||||
if( pxTCB->xEventListItem.pvContainer != NULL )
|
||||
|
@ -1690,17 +1758,8 @@ void vTaskSwitchContext( void )
|
|||
taskFIRST_CHECK_FOR_STACK_OVERFLOW();
|
||||
taskSECOND_CHECK_FOR_STACK_OVERFLOW();
|
||||
|
||||
/* Find the highest priority queue that contains ready tasks. */
|
||||
while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) )
|
||||
{
|
||||
configASSERT( uxTopReadyPriority );
|
||||
--uxTopReadyPriority;
|
||||
}
|
||||
|
||||
/* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the tasks of the
|
||||
same priority get an equal share of the processor time. */
|
||||
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) );
|
||||
|
||||
taskSELECT_HIGHEST_PRIORITY_TASK();
|
||||
|
||||
traceTASK_SWITCHED_IN();
|
||||
}
|
||||
}
|
||||
|
@ -1724,7 +1783,7 @@ portTickType xTimeToWake;
|
|||
to the blocked list as the same list item is used for both lists. We have
|
||||
exclusive access to the ready lists as the scheduler is locked. */
|
||||
vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
|
||||
|
||||
taskCHECK_READY_LIST( pxCurrentTCB->uxPriority );
|
||||
|
||||
#if ( INCLUDE_vTaskSuspend == 1 )
|
||||
{
|
||||
|
@ -1778,6 +1837,7 @@ portTickType xTimeToWake;
|
|||
blocked list as the same list item is used for both lists. This
|
||||
function is called form a critical section. */
|
||||
vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
|
||||
taskCHECK_READY_LIST( pxCurrentTCB->uxPriority );
|
||||
|
||||
/* Calculate the time at which the task should be woken if the event does
|
||||
not occur. This may overflow but this doesn't matter. */
|
||||
|
@ -2458,6 +2518,7 @@ tskTCB *pxNewTCB;
|
|||
if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ) != pdFALSE )
|
||||
{
|
||||
vListRemove( &( pxTCB->xGenericListItem ) );
|
||||
taskCHECK_READY_LIST( pxTCB->uxPriority );
|
||||
|
||||
/* Inherit the priority before being moved into the new list. */
|
||||
pxTCB->uxPriority = pxCurrentTCB->uxPriority;
|
||||
|
@ -2490,6 +2551,7 @@ tskTCB *pxNewTCB;
|
|||
/* We must be the running task to be able to give the mutex back.
|
||||
Remove ourselves from the ready list we currently appear in. */
|
||||
vListRemove( &( pxTCB->xGenericListItem ) );
|
||||
taskCHECK_READY_LIST( pxTCB->uxPriority );
|
||||
|
||||
/* Disinherit the priority before adding the task into the new
|
||||
ready list. */
|
||||
|
|
Loading…
Reference in a new issue