mirror of
https://github.com/FreeRTOS/FreeRTOS.git
synced 2025-05-17 15:06:34 +08:00
Add async core yield test for SMP (#1247)
Add async core yield test for SMP Add async core yield test for SMP to verify set core affinity implementation
This commit is contained in:
Submodule FreeRTOS/Source updated: 53c7e7c46f...e43553af1e
@ -3499,3 +3499,85 @@ void test_task_priority_inherit_disinherit_timeout( void )
|
||||
/* Verify that the low priority task is ready. */
|
||||
verifySmpTask( &xTaskHandles[ configNUMBER_OF_CORES ], eReady, -1 );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief AWS_IoT-FreeRTOS_SMP_TC-110
|
||||
* Yield for the task when setting the core affinity of a task of ready state. This
|
||||
* situation happens when the core can't select the task to run before the task
|
||||
* core affinity is changed. The vTaskCoreAffinitySet should request a core on which
|
||||
* the task is able to run with new core affinity setting.
|
||||
*
|
||||
* #define configRUN_MULTIPLE_PRIORITIES 1
|
||||
* #define configUSE_TIME_SLICING 0
|
||||
* #define configUSE_CORE_AFFINITY 1
|
||||
* #define configNUMBER_OF_CORES (N > 2)
|
||||
*
|
||||
* This test can be run with FreeRTOS configured for any number of cores greater
|
||||
* than 2.
|
||||
*
|
||||
* Tasks are created prior to starting the scheduler
|
||||
*
|
||||
* Main task (T1)
|
||||
* Priority – 3
|
||||
* State – Ready
|
||||
*
|
||||
* After calling vTaskStartScheduler()
|
||||
*
|
||||
* Main task (T1)
|
||||
* Priority – 3
|
||||
* State – Running( 0 )
|
||||
*
|
||||
* After creating the core task with xTaskCreate(). Core 2 was requested to yield
|
||||
* but not yet able to select core task.
|
||||
*
|
||||
* Main task (T1) Core Task (T2)
|
||||
* Priority – 3 Priority – 3
|
||||
* State – Running( 0 ) State – Ready
|
||||
*
|
||||
* After setting the core affinity of the core task to core 1 only with vTaskCoreAffinitySet().
|
||||
*
|
||||
* Main task (T1) Core Task (T2)
|
||||
* Priority – 3 Priority – 3
|
||||
* State – Running( 0 ) Affinity – ( 1 )
|
||||
* State – Ready
|
||||
*
|
||||
* After async core yield for core task.
|
||||
*
|
||||
* Main Task (T1) Core Task (T2)
|
||||
* Priority – 3 Priority – 3
|
||||
* State – Running( 0 ) Affinity – ( 1 )
|
||||
* State – Running( 1 )
|
||||
*
|
||||
*/
|
||||
void test_task_create_task_set_affinity_async_yield( void )
|
||||
{
|
||||
TaskHandle_t xMainTaskHandle;
|
||||
TaskHandle_t xCoreTaskHandle;
|
||||
BaseType_t xCoreID;
|
||||
|
||||
/* The core yield should be manually triggered in the test cases when using
|
||||
* async core yield setup. */
|
||||
commonAsyncCoreYieldSetup();
|
||||
|
||||
/* Create high priority main task. */
|
||||
xTaskCreate( vSmpTestTask, "SMP Task", configMINIMAL_STACK_SIZE, NULL, 3, &xMainTaskHandle );
|
||||
|
||||
/* Start the scheduler. */
|
||||
vTaskStartScheduler();
|
||||
|
||||
/* Create high priority core task. */
|
||||
xTaskCreate( vSmpTestTask, "SMP Task", configMINIMAL_STACK_SIZE, NULL, 3, &xCoreTaskHandle );
|
||||
|
||||
/* Set the core affinity of the core task to core 1. */
|
||||
vTaskCoreAffinitySet( xCoreTaskHandle, ( 1 << 1 ) );
|
||||
|
||||
/* Core yield is called here to simulate SMP asynchronous behavior. */
|
||||
for( xCoreID = 0; xCoreID < configNUMBER_OF_CORES; xCoreID++ )
|
||||
{
|
||||
vCheckAndExecuteAsyncCoreYield( xCoreID );
|
||||
}
|
||||
|
||||
/* Verify that the task core task can run on core 1. */
|
||||
verifySmpTask( &xCoreTaskHandle, eRunning, 1 );
|
||||
}
|
||||
|
@ -154,6 +154,14 @@ void vFakePortYieldCoreStubCallback( int xCoreID,
|
||||
}
|
||||
}
|
||||
|
||||
void vFakePortYieldCoreAsyncStubCallback( int xCoreID,
|
||||
int cmock_num_calls )
|
||||
{
|
||||
( void ) cmock_num_calls;
|
||||
|
||||
xCoreYields[ xCoreID ] = pdTRUE;
|
||||
}
|
||||
|
||||
void vFakePortYieldStubCallback( int cmock_num_calls )
|
||||
{
|
||||
vTaskSwitchContext( xCurrentCoreId );
|
||||
@ -182,6 +190,34 @@ void vSetCurrentCore( BaseType_t xCoreID )
|
||||
xCurrentCoreId = xCoreID;
|
||||
}
|
||||
|
||||
void vCheckAndExecuteAsyncCoreYield( BaseType_t xCoreID )
|
||||
{
|
||||
BaseType_t xCoreInCritical = pdFALSE;
|
||||
BaseType_t xPreviousCoreId = xCurrentCoreId;
|
||||
int i;
|
||||
|
||||
if( xCoreYields[ xCoreID ] != pdFALSE )
|
||||
{
|
||||
/* Check if the lock is acquired by any core. */
|
||||
for( i = 0; i < configNUMBER_OF_CORES; i++ )
|
||||
{
|
||||
if( ( xIsrLockCount[ i ] > 0 ) || ( xTaskLockCount[ i ] > 0 ) )
|
||||
{
|
||||
xCoreInCritical = pdTRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( xCoreInCritical != pdTRUE )
|
||||
{
|
||||
/* No task is in the critical section. We can yield this core. */
|
||||
xCurrentCoreId = xCoreID;
|
||||
vTaskSwitchContext( xCurrentCoreId );
|
||||
xCurrentCoreId = xPreviousCoreId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void vYieldCores( void )
|
||||
{
|
||||
BaseType_t i;
|
||||
@ -265,6 +301,14 @@ void vFakePortReleaseTaskLockCallback( int cmock_num_calls )
|
||||
}
|
||||
}
|
||||
|
||||
void vFakePortReleaseTaskLockAsyncCallback( int cmock_num_calls )
|
||||
{
|
||||
( void ) cmock_num_calls;
|
||||
|
||||
TEST_ASSERT_MESSAGE( xTaskLockCount[ xCurrentCoreId ] > 0, "xTaskLockCount[ xCurrentCoreId ] <= 0" );
|
||||
xTaskLockCount[ xCurrentCoreId ]--;
|
||||
}
|
||||
|
||||
portBASE_TYPE vFakePortEnterCriticalFromISRCallback( int cmock_num_calls )
|
||||
{
|
||||
portBASE_TYPE xSavedInterruptState;
|
||||
@ -281,6 +325,12 @@ void vFakePortExitCriticalFromISRCallback( portBASE_TYPE xSavedInterruptState,
|
||||
vYieldCores();
|
||||
}
|
||||
|
||||
void vFakePortExitCriticalFromISRAsyncCallback( portBASE_TYPE xSavedInterruptState,
|
||||
int cmock_num_calls )
|
||||
{
|
||||
vTaskExitCriticalFromISR( xSavedInterruptState );
|
||||
}
|
||||
|
||||
/* ============================= Unity Fixtures ============================= */
|
||||
|
||||
void commonSetUp( void )
|
||||
@ -342,6 +392,13 @@ void commonSetUp( void )
|
||||
memset( xIsrLockCount, 0x00, sizeof( xIsrLockCount ) );
|
||||
}
|
||||
|
||||
void commonAsyncCoreYieldSetup( void )
|
||||
{
|
||||
vFakePortYieldCore_StubWithCallback( vFakePortYieldCoreAsyncStubCallback );
|
||||
vFakePortExitCriticalFromISR_StubWithCallback( vFakePortExitCriticalFromISRAsyncCallback );
|
||||
vFakePortReleaseTaskLock_StubWithCallback( vFakePortReleaseTaskLockAsyncCallback );
|
||||
}
|
||||
|
||||
void commonTearDown( void )
|
||||
{
|
||||
}
|
||||
|
@ -65,6 +65,12 @@ void vPortFree( void * pv );
|
||||
*/
|
||||
void commonSetUp( void );
|
||||
|
||||
/**
|
||||
* @brief Common test case asyncrhonous core yield setup function for SMP tests.
|
||||
* This API should be called after commonSetUp().
|
||||
*/
|
||||
void commonAsyncCoreYieldSetup( void );
|
||||
|
||||
/**
|
||||
* @brief Common test case teardown function for SMP tests.
|
||||
*/
|
||||
@ -98,6 +104,11 @@ void xTaskIncrementTick_helper( void );
|
||||
*/
|
||||
void vSetCurrentCore( BaseType_t xCoreID );
|
||||
|
||||
/**
|
||||
* @brief Check and execut asynchronous core yield request.
|
||||
*/
|
||||
void vCheckAndExecuteAsyncCoreYield( BaseType_t xCoreID );
|
||||
|
||||
/**
|
||||
* @brief Helper function to create static test task.
|
||||
*/
|
||||
|
@ -5,7 +5,7 @@ license: "MIT"
|
||||
|
||||
dependencies:
|
||||
- name: "FreeRTOS-Kernel"
|
||||
version: "53c7e7c46"
|
||||
version: "e43553af1"
|
||||
repository:
|
||||
type: "git"
|
||||
url: "https://github.com/FreeRTOS/FreeRTOS-Kernel.git"
|
||||
|
Reference in New Issue
Block a user