Skip to content

Commit 9febced

Browse files
authored
Add async core yield test for SMP (FreeRTOS#1247)
Add async core yield test for SMP Add async core yield test for SMP to verify set core affinity implementation
1 parent 1a82df0 commit 9febced

File tree

5 files changed

+152
-2
lines changed

5 files changed

+152
-2
lines changed

FreeRTOS/Test/CMock/smp/multiple_priorities_no_timeslice/multiple_priorities_no_timeslice_utest.c

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3499,3 +3499,85 @@ void test_task_priority_inherit_disinherit_timeout( void )
34993499
/* Verify that the low priority task is ready. */
35003500
verifySmpTask( &xTaskHandles[ configNUMBER_OF_CORES ], eReady, -1 );
35013501
}
3502+
3503+
3504+
/**
3505+
* @brief AWS_IoT-FreeRTOS_SMP_TC-110
3506+
* Yield for the task when setting the core affinity of a task of ready state. This
3507+
* situation happens when the core can't select the task to run before the task
3508+
* core affinity is changed. The vTaskCoreAffinitySet should request a core on which
3509+
* the task is able to run with new core affinity setting.
3510+
*
3511+
* #define configRUN_MULTIPLE_PRIORITIES 1
3512+
* #define configUSE_TIME_SLICING 0
3513+
* #define configUSE_CORE_AFFINITY 1
3514+
* #define configNUMBER_OF_CORES (N > 2)
3515+
*
3516+
* This test can be run with FreeRTOS configured for any number of cores greater
3517+
* than 2.
3518+
*
3519+
* Tasks are created prior to starting the scheduler
3520+
*
3521+
* Main task (T1)
3522+
* Priority – 3
3523+
* State – Ready
3524+
*
3525+
* After calling vTaskStartScheduler()
3526+
*
3527+
* Main task (T1)
3528+
* Priority – 3
3529+
* State – Running( 0 )
3530+
*
3531+
* After creating the core task with xTaskCreate(). Core 2 was requested to yield
3532+
* but not yet able to select core task.
3533+
*
3534+
* Main task (T1) Core Task (T2)
3535+
* Priority – 3 Priority – 3
3536+
* State – Running( 0 ) State – Ready
3537+
*
3538+
* After setting the core affinity of the core task to core 1 only with vTaskCoreAffinitySet().
3539+
*
3540+
* Main task (T1) Core Task (T2)
3541+
* Priority – 3 Priority – 3
3542+
* State – Running( 0 ) Affinity – ( 1 )
3543+
* State – Ready
3544+
*
3545+
* After async core yield for core task.
3546+
*
3547+
* Main Task (T1) Core Task (T2)
3548+
* Priority – 3 Priority – 3
3549+
* State – Running( 0 ) Affinity – ( 1 )
3550+
* State – Running( 1 )
3551+
*
3552+
*/
3553+
void test_task_create_task_set_affinity_async_yield( void )
3554+
{
3555+
TaskHandle_t xMainTaskHandle;
3556+
TaskHandle_t xCoreTaskHandle;
3557+
BaseType_t xCoreID;
3558+
3559+
/* The core yield should be manually triggered in the test cases when using
3560+
* async core yield setup. */
3561+
commonAsyncCoreYieldSetup();
3562+
3563+
/* Create high priority main task. */
3564+
xTaskCreate( vSmpTestTask, "SMP Task", configMINIMAL_STACK_SIZE, NULL, 3, &xMainTaskHandle );
3565+
3566+
/* Start the scheduler. */
3567+
vTaskStartScheduler();
3568+
3569+
/* Create high priority core task. */
3570+
xTaskCreate( vSmpTestTask, "SMP Task", configMINIMAL_STACK_SIZE, NULL, 3, &xCoreTaskHandle );
3571+
3572+
/* Set the core affinity of the core task to core 1. */
3573+
vTaskCoreAffinitySet( xCoreTaskHandle, ( 1 << 1 ) );
3574+
3575+
/* Core yield is called here to simulate SMP asynchronous behavior. */
3576+
for( xCoreID = 0; xCoreID < configNUMBER_OF_CORES; xCoreID++ )
3577+
{
3578+
vCheckAndExecuteAsyncCoreYield( xCoreID );
3579+
}
3580+
3581+
/* Verify that the task core task can run on core 1. */
3582+
verifySmpTask( &xCoreTaskHandle, eRunning, 1 );
3583+
}

FreeRTOS/Test/CMock/smp/smp_utest_common.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,14 @@ void vFakePortYieldCoreStubCallback( int xCoreID,
154154
}
155155
}
156156

157+
void vFakePortYieldCoreAsyncStubCallback( int xCoreID,
158+
int cmock_num_calls )
159+
{
160+
( void ) cmock_num_calls;
161+
162+
xCoreYields[ xCoreID ] = pdTRUE;
163+
}
164+
157165
void vFakePortYieldStubCallback( int cmock_num_calls )
158166
{
159167
vTaskSwitchContext( xCurrentCoreId );
@@ -182,6 +190,34 @@ void vSetCurrentCore( BaseType_t xCoreID )
182190
xCurrentCoreId = xCoreID;
183191
}
184192

193+
void vCheckAndExecuteAsyncCoreYield( BaseType_t xCoreID )
194+
{
195+
BaseType_t xCoreInCritical = pdFALSE;
196+
BaseType_t xPreviousCoreId = xCurrentCoreId;
197+
int i;
198+
199+
if( xCoreYields[ xCoreID ] != pdFALSE )
200+
{
201+
/* Check if the lock is acquired by any core. */
202+
for( i = 0; i < configNUMBER_OF_CORES; i++ )
203+
{
204+
if( ( xIsrLockCount[ i ] > 0 ) || ( xTaskLockCount[ i ] > 0 ) )
205+
{
206+
xCoreInCritical = pdTRUE;
207+
break;
208+
}
209+
}
210+
211+
if( xCoreInCritical != pdTRUE )
212+
{
213+
/* No task is in the critical section. We can yield this core. */
214+
xCurrentCoreId = xCoreID;
215+
vTaskSwitchContext( xCurrentCoreId );
216+
xCurrentCoreId = xPreviousCoreId;
217+
}
218+
}
219+
}
220+
185221
static void vYieldCores( void )
186222
{
187223
BaseType_t i;
@@ -265,6 +301,14 @@ void vFakePortReleaseTaskLockCallback( int cmock_num_calls )
265301
}
266302
}
267303

304+
void vFakePortReleaseTaskLockAsyncCallback( int cmock_num_calls )
305+
{
306+
( void ) cmock_num_calls;
307+
308+
TEST_ASSERT_MESSAGE( xTaskLockCount[ xCurrentCoreId ] > 0, "xTaskLockCount[ xCurrentCoreId ] <= 0" );
309+
xTaskLockCount[ xCurrentCoreId ]--;
310+
}
311+
268312
portBASE_TYPE vFakePortEnterCriticalFromISRCallback( int cmock_num_calls )
269313
{
270314
portBASE_TYPE xSavedInterruptState;
@@ -281,6 +325,12 @@ void vFakePortExitCriticalFromISRCallback( portBASE_TYPE xSavedInterruptState,
281325
vYieldCores();
282326
}
283327

328+
void vFakePortExitCriticalFromISRAsyncCallback( portBASE_TYPE xSavedInterruptState,
329+
int cmock_num_calls )
330+
{
331+
vTaskExitCriticalFromISR( xSavedInterruptState );
332+
}
333+
284334
/* ============================= Unity Fixtures ============================= */
285335

286336
void commonSetUp( void )
@@ -342,6 +392,13 @@ void commonSetUp( void )
342392
memset( xIsrLockCount, 0x00, sizeof( xIsrLockCount ) );
343393
}
344394

395+
void commonAsyncCoreYieldSetup( void )
396+
{
397+
vFakePortYieldCore_StubWithCallback( vFakePortYieldCoreAsyncStubCallback );
398+
vFakePortExitCriticalFromISR_StubWithCallback( vFakePortExitCriticalFromISRAsyncCallback );
399+
vFakePortReleaseTaskLock_StubWithCallback( vFakePortReleaseTaskLockAsyncCallback );
400+
}
401+
345402
void commonTearDown( void )
346403
{
347404
}

FreeRTOS/Test/CMock/smp/smp_utest_common.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ void vPortFree( void * pv );
6565
*/
6666
void commonSetUp( void );
6767

68+
/**
69+
* @brief Common test case asyncrhonous core yield setup function for SMP tests.
70+
* This API should be called after commonSetUp().
71+
*/
72+
void commonAsyncCoreYieldSetup( void );
73+
6874
/**
6975
* @brief Common test case teardown function for SMP tests.
7076
*/
@@ -98,6 +104,11 @@ void xTaskIncrementTick_helper( void );
98104
*/
99105
void vSetCurrentCore( BaseType_t xCoreID );
100106

107+
/**
108+
* @brief Check and execut asynchronous core yield request.
109+
*/
110+
void vCheckAndExecuteAsyncCoreYield( BaseType_t xCoreID );
111+
101112
/**
102113
* @brief Helper function to create static test task.
103114
*/

manifest.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ license: "MIT"
55

66
dependencies:
77
- name: "FreeRTOS-Kernel"
8-
version: "53c7e7c46"
8+
version: "e43553af1"
99
repository:
1010
type: "git"
1111
url: "https://github.com/FreeRTOS/FreeRTOS-Kernel.git"

0 commit comments

Comments
 (0)