mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-20 05:21:59 -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_QUEUE_LENGTH 20
|
||||||
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
|
#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 )
|
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
||||||
|
|
||||||
|
|
||||||
|
@ -132,4 +132,9 @@ to exclude the API function. */
|
||||||
extern void vAssertCalled( void );
|
extern void vAssertCalled( void );
|
||||||
#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled()
|
#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 */
|
#endif /* FREERTOS_CONFIG_H */
|
||||||
|
|
|
@ -165,6 +165,10 @@ typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * );
|
||||||
#define INCLUDE_uxTaskGetStackHighWaterMark 0
|
#define INCLUDE_uxTaskGetStackHighWaterMark 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef INCLUDE_cTaskStateGet
|
#ifndef INCLUDE_cTaskStateGet
|
||||||
#define INCLUDE_cTaskStateGet 0
|
#define INCLUDE_cTaskStateGet 0
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -108,6 +108,30 @@ void vPortExitCritical( void );
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#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. */
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( 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
|
* 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
|
* 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 ) \
|
#define prvAddTaskToReadyQueue( pxTCB ) \
|
||||||
traceMOVED_TASK_TO_READY_STATE( pxTCB ) \
|
traceMOVED_TASK_TO_READY_STATE( pxTCB ) \
|
||||||
if( ( pxTCB )->uxPriority > uxTopReadyPriority ) \
|
taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority ); \
|
||||||
{ \
|
|
||||||
uxTopReadyPriority = ( pxTCB )->uxPriority; \
|
|
||||||
} \
|
|
||||||
vListInsertEnd( ( xList * ) &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xGenericListItem ) )
|
vListInsertEnd( ( xList * ) &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xGenericListItem ) )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -579,6 +642,7 @@ tskTCB * pxNewTCB;
|
||||||
the termination list and free up any memory allocated by the
|
the termination list and free up any memory allocated by the
|
||||||
scheduler for the TCB and stack. */
|
scheduler for the TCB and stack. */
|
||||||
vListRemove( &( pxTCB->xGenericListItem ) );
|
vListRemove( &( pxTCB->xGenericListItem ) );
|
||||||
|
taskCHECK_READY_LIST( pxTCB->uxPriority );
|
||||||
|
|
||||||
/* Is the task waiting on an event also? */
|
/* Is the task waiting on an event also? */
|
||||||
if( pxTCB->xEventListItem.pvContainer != NULL )
|
if( pxTCB->xEventListItem.pvContainer != NULL )
|
||||||
|
@ -671,6 +735,7 @@ tskTCB * pxNewTCB;
|
||||||
ourselves to the blocked list as the same list item is used for
|
ourselves to the blocked list as the same list item is used for
|
||||||
both lists. */
|
both lists. */
|
||||||
vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
|
vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
|
||||||
|
taskCHECK_READY_LIST( pxCurrentTCB->uxPriority );
|
||||||
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -717,6 +782,7 @@ tskTCB * pxNewTCB;
|
||||||
ourselves to the blocked list as the same list item is used for
|
ourselves to the blocked list as the same list item is used for
|
||||||
both lists. */
|
both lists. */
|
||||||
vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
|
vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
|
||||||
|
taskCHECK_READY_LIST( pxCurrentTCB->uxPriority );
|
||||||
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||||
}
|
}
|
||||||
xAlreadyYielded = xTaskResumeAll();
|
xAlreadyYielded = xTaskResumeAll();
|
||||||
|
@ -910,6 +976,7 @@ tskTCB * pxNewTCB;
|
||||||
it to it's new ready list. As we are in a critical section we
|
it to it's new ready list. As we are in a critical section we
|
||||||
can do this even if the scheduler is suspended. */
|
can do this even if the scheduler is suspended. */
|
||||||
vListRemove( &( pxTCB->xGenericListItem ) );
|
vListRemove( &( pxTCB->xGenericListItem ) );
|
||||||
|
taskCHECK_READY_LIST( uxCurrentPriority );
|
||||||
prvAddTaskToReadyQueue( pxTCB );
|
prvAddTaskToReadyQueue( pxTCB );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -947,6 +1014,7 @@ tskTCB * pxNewTCB;
|
||||||
|
|
||||||
/* Remove task from the ready/delayed list and place in the suspended list. */
|
/* Remove task from the ready/delayed list and place in the suspended list. */
|
||||||
vListRemove( &( pxTCB->xGenericListItem ) );
|
vListRemove( &( pxTCB->xGenericListItem ) );
|
||||||
|
taskCHECK_READY_LIST( pxTCB->uxPriority );
|
||||||
|
|
||||||
/* Is the task waiting on an event also? */
|
/* Is the task waiting on an event also? */
|
||||||
if( pxTCB->xEventListItem.pvContainer != NULL )
|
if( pxTCB->xEventListItem.pvContainer != NULL )
|
||||||
|
@ -1690,16 +1758,7 @@ void vTaskSwitchContext( void )
|
||||||
taskFIRST_CHECK_FOR_STACK_OVERFLOW();
|
taskFIRST_CHECK_FOR_STACK_OVERFLOW();
|
||||||
taskSECOND_CHECK_FOR_STACK_OVERFLOW();
|
taskSECOND_CHECK_FOR_STACK_OVERFLOW();
|
||||||
|
|
||||||
/* Find the highest priority queue that contains ready tasks. */
|
taskSELECT_HIGHEST_PRIORITY_TASK();
|
||||||
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 ] ) );
|
|
||||||
|
|
||||||
traceTASK_SWITCHED_IN();
|
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
|
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. */
|
exclusive access to the ready lists as the scheduler is locked. */
|
||||||
vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
|
vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
|
||||||
|
taskCHECK_READY_LIST( pxCurrentTCB->uxPriority );
|
||||||
|
|
||||||
#if ( INCLUDE_vTaskSuspend == 1 )
|
#if ( INCLUDE_vTaskSuspend == 1 )
|
||||||
{
|
{
|
||||||
|
@ -1778,6 +1837,7 @@ portTickType xTimeToWake;
|
||||||
blocked list as the same list item is used for both lists. This
|
blocked list as the same list item is used for both lists. This
|
||||||
function is called form a critical section. */
|
function is called form a critical section. */
|
||||||
vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
|
vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
|
||||||
|
taskCHECK_READY_LIST( pxCurrentTCB->uxPriority );
|
||||||
|
|
||||||
/* Calculate the time at which the task should be woken if the event does
|
/* Calculate the time at which the task should be woken if the event does
|
||||||
not occur. This may overflow but this doesn't matter. */
|
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 )
|
if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ) != pdFALSE )
|
||||||
{
|
{
|
||||||
vListRemove( &( pxTCB->xGenericListItem ) );
|
vListRemove( &( pxTCB->xGenericListItem ) );
|
||||||
|
taskCHECK_READY_LIST( pxTCB->uxPriority );
|
||||||
|
|
||||||
/* Inherit the priority before being moved into the new list. */
|
/* Inherit the priority before being moved into the new list. */
|
||||||
pxTCB->uxPriority = pxCurrentTCB->uxPriority;
|
pxTCB->uxPriority = pxCurrentTCB->uxPriority;
|
||||||
|
@ -2490,6 +2551,7 @@ tskTCB *pxNewTCB;
|
||||||
/* We must be the running task to be able to give the mutex back.
|
/* We must be the running task to be able to give the mutex back.
|
||||||
Remove ourselves from the ready list we currently appear in. */
|
Remove ourselves from the ready list we currently appear in. */
|
||||||
vListRemove( &( pxTCB->xGenericListItem ) );
|
vListRemove( &( pxTCB->xGenericListItem ) );
|
||||||
|
taskCHECK_READY_LIST( pxTCB->uxPriority );
|
||||||
|
|
||||||
/* Disinherit the priority before adding the task into the new
|
/* Disinherit the priority before adding the task into the new
|
||||||
ready list. */
|
ready list. */
|
||||||
|
|
Loading…
Reference in a new issue