mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-10-18 10:47:47 -04: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:
parent
1a82df09df
commit
9febcedd91
5 changed files with 152 additions and 2 deletions
|
@ -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. */
|
/* Verify that the low priority task is ready. */
|
||||||
verifySmpTask( &xTaskHandles[ configNUMBER_OF_CORES ], eReady, -1 );
|
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 )
|
void vFakePortYieldStubCallback( int cmock_num_calls )
|
||||||
{
|
{
|
||||||
vTaskSwitchContext( xCurrentCoreId );
|
vTaskSwitchContext( xCurrentCoreId );
|
||||||
|
@ -182,6 +190,34 @@ void vSetCurrentCore( BaseType_t xCoreID )
|
||||||
xCurrentCoreId = 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 )
|
static void vYieldCores( void )
|
||||||
{
|
{
|
||||||
BaseType_t i;
|
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 vFakePortEnterCriticalFromISRCallback( int cmock_num_calls )
|
||||||
{
|
{
|
||||||
portBASE_TYPE xSavedInterruptState;
|
portBASE_TYPE xSavedInterruptState;
|
||||||
|
@ -281,6 +325,12 @@ void vFakePortExitCriticalFromISRCallback( portBASE_TYPE xSavedInterruptState,
|
||||||
vYieldCores();
|
vYieldCores();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vFakePortExitCriticalFromISRAsyncCallback( portBASE_TYPE xSavedInterruptState,
|
||||||
|
int cmock_num_calls )
|
||||||
|
{
|
||||||
|
vTaskExitCriticalFromISR( xSavedInterruptState );
|
||||||
|
}
|
||||||
|
|
||||||
/* ============================= Unity Fixtures ============================= */
|
/* ============================= Unity Fixtures ============================= */
|
||||||
|
|
||||||
void commonSetUp( void )
|
void commonSetUp( void )
|
||||||
|
@ -342,6 +392,13 @@ void commonSetUp( void )
|
||||||
memset( xIsrLockCount, 0x00, sizeof( xIsrLockCount ) );
|
memset( xIsrLockCount, 0x00, sizeof( xIsrLockCount ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void commonAsyncCoreYieldSetup( void )
|
||||||
|
{
|
||||||
|
vFakePortYieldCore_StubWithCallback( vFakePortYieldCoreAsyncStubCallback );
|
||||||
|
vFakePortExitCriticalFromISR_StubWithCallback( vFakePortExitCriticalFromISRAsyncCallback );
|
||||||
|
vFakePortReleaseTaskLock_StubWithCallback( vFakePortReleaseTaskLockAsyncCallback );
|
||||||
|
}
|
||||||
|
|
||||||
void commonTearDown( void )
|
void commonTearDown( void )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,12 @@ void vPortFree( void * pv );
|
||||||
*/
|
*/
|
||||||
void commonSetUp( void );
|
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.
|
* @brief Common test case teardown function for SMP tests.
|
||||||
*/
|
*/
|
||||||
|
@ -98,6 +104,11 @@ void xTaskIncrementTick_helper( void );
|
||||||
*/
|
*/
|
||||||
void vSetCurrentCore( BaseType_t xCoreID );
|
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.
|
* @brief Helper function to create static test task.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -5,7 +5,7 @@ license: "MIT"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
- name: "FreeRTOS-Kernel"
|
- name: "FreeRTOS-Kernel"
|
||||||
version: "53c7e7c46"
|
version: "e43553af1"
|
||||||
repository:
|
repository:
|
||||||
type: "git"
|
type: "git"
|
||||||
url: "https://github.com/FreeRTOS/FreeRTOS-Kernel.git"
|
url: "https://github.com/FreeRTOS/FreeRTOS-Kernel.git"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue