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
pull/1254/head
chinglee-iot 5 months ago committed by GitHub
parent 1a82df09df
commit 9febcedd91
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1 +1 @@
Subproject commit 53c7e7c46f20dbd941d3f17116725d8fda9e6b90
Subproject commit e43553af1e3d19a1eec27593c332f97e986cbd1c

@ -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"

Loading…
Cancel
Save