Skip to content

Commit

Permalink
Add async core yield test for SMP (FreeRTOS#1247)
Browse files Browse the repository at this point in the history
Add async core yield test for SMP

Add async core yield test for SMP to verify set core affinity
  implementation
  • Loading branch information
chinglee-iot authored Aug 21, 2024
1 parent 1a82df0 commit 9febced
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
}
57 changes: 57 additions & 0 deletions FreeRTOS/Test/CMock/smp/smp_utest_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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 )
Expand Down Expand Up @@ -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 )
{
}
Expand Down
11 changes: 11 additions & 0 deletions FreeRTOS/Test/CMock/smp/smp_utest_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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.
*/
Expand Down
2 changes: 1 addition & 1 deletion manifest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

0 comments on commit 9febced

Please sign in to comment.