Schedulerer problem in smp system

Hi,

I have a scheduler problem when test affinity API on cortex-a32*2 aarch32.
The test code is as follows:

    xTaskCreate(vTask1, "Task 1", 1000, NULL, 1, &xTask1);
    xTaskCreate(vTask2, "Task 2", 1000, NULL, 2, &xTask2);
    xTaskCreate(vTask3, "Task 3", 1000, NULL, 3, &xTask3);

    uxTask1Mask = ( (1 << 1) );
    vTaskCoreAffinitySet( xTask1, uxTask1Mask);
    uxTask2Mask = ( (1 << 1) );
    vTaskCoreAffinitySet( xTask2, uxTask2Mask );
    uxTask3Mask = ( (1 << 0) );
    vTaskCoreAffinitySet( xTask3, uxTask3Mask );
static void vTask1( void *pvParameters )
{
    int i;
    volatile uint32_t x = 0;
    for( ;; )
    {
        printf("T1, Core 1, Prio 1\n" );
        vTaskDelay(mainQUEUE_SEND_PERIOD_MS);
    }
}

static void vTask2( void *pvParameters )
{
    int i;
    volatile uint32_t x = 0;
    for( ;; )
    {
        printf("T2, Core 1, Prio 2\n");
        vTaskDelay(mainQUEUE_SEND_PERIOD_MS);
    }
}

static void vTask3( void *pvParameters )
{
    int i;
    volatile uint32_t x = 0;
    for( ;; )
    {
        printf("T3, Core 0, Prio 3\n");
        vTaskDelay(mainQUEUE_SEND_PERIOD_MS);
    }
}

At the beginning the print is correct, but after running for a while task1 and task2 runing on core 1 are not scheduled. They both are removed from delay list and in ready list. Task3 can run on core0. I can not trace the problem.

pxReadyTaskList = {{uxNumberOfItems = 2, pxIndex = 0x8042135c <pxReadyTasksLists+8>, xListEnd = {xItemValue = 4294967295, pxNext = 0x80421874 <xIdleTCBBuffers.0+8>, pxPrevious = 0x80420278 <xIdleTaskTCB.3+8>}}, {
    uxNumberOfItems = 1, pxIndex = 0x80421370 <pxReadyTasksLists+28>, xListEnd = {xItemValue = 4294967295, pxNext = 0x804229b8 <ucHeap+4036>, pxPrevious = 0x804229b8 <ucHeap+4036>}}, {
    uxNumberOfItems = 1, pxIndex = 0x80421384 <pxReadyTasksLists+48>, xListEnd = {xItemValue = 4294967295, pxNext = 0x804239e0 <ucHeap+8172>, pxPrevious = 0x804239e0 <ucHeap+8172>}}, {

Can give some debugging suggestions, thank you very much!

One big question, is your printf function “Task Safe”?

Sorry I don’t understand “Task Safe", I think it is not thread safe.

“Task Safe” means usable in multiple tasks, since that is what FreeRTOS uses.

If it isn’t thread-safe, then in it isn’t likely Task Safe. Note, the way you are using it, you may get switching in the middle of a print call between vTask1 and vTask2.

Thanks for your reply. But the code is just to test the scheduler. Using queue to test also meets the same problem - the task on core1 is’t be sheduled.

Are you writing a new port for SMP?

Can you examine the TCBs of task1 and task2 in the debugger and see their state when the problem happens? Is the portYIELD_CORE macro implemented correctly to interrupt other core?

Yes,I modify the portable file based on FreeRRTOS on Cortex-A.

The state of two tasks running on core 1 are taskTASK_NOT_RUNNING.

{pxTopOfStack = 0x80422810 <ucHeap+3612>, uxCoreAffinityMask = 2, xStateListItem = {xItemValue = 9001, pxNext = 0x80421370 <pxReadyTasksLists+28>, pxPrevious = 0x80421370 <pxReadyTasksLists+28>,
    pvOwner = 0x804229b0 <ucHeap+4028>, pvContainer = 0x80421368 <pxReadyTasksLists+20>}, xEventListItem = {xItemValue = 6, pxNext = 0x0, pxPrevious = 0x0, pvOwner = 0x804229b0 <ucHeap+4028>,
    pvContainer = 0x0}, uxPriority = 1, pxStack = 0x80421a00 <ucHeap+12>, xTaskRunState = -1, xIsIdle = 0, pcTaskName = "Task 1\000\000\000", uxCriticalNesting = 0, uxTCBNumber = 1, uxTaskNumber = 0,
  uxBasePriority = 1, uxMutexesHeld = 0, ulNotifiedValue = {0}, ucNotifyState = "", ucStaticallyAllocated = 0 '\000', ucDelayAborted = 0 '\000'}
{pxTopOfStack = 0x80423838 <ucHeap+7748>, uxCoreAffinityMask = 2, xStateListItem = {xItemValue = 9000, pxNext = 0x80421384 <pxReadyTasksLists+48>, pxPrevious = 0x80421384 <pxReadyTasksLists+48>,
    pvOwner = 0x804239d8 <ucHeap+8164>, pvContainer = 0x8042137c <pxReadyTasksLists+40>}, xEventListItem = {xItemValue = 5, pxNext = 0x0, pxPrevious = 0x0, pvOwner = 0x804239d8 <ucHeap+8164>,
    pvContainer = 0x0}, uxPriority = 2, pxStack = 0x80422a28 <ucHeap+4148>, xTaskRunState = -1, xIsIdle = 0, pcTaskName = "Task 2\000\000\000", uxCriticalNesting = 0, uxTCBNumber = 2,
  uxTaskNumber = 0, uxBasePriority = 2, uxMutexesHeld = 0, ulNotifiedValue = {0}, ucNotifyState = "", ucStaticallyAllocated = 0 '\000', ucDelayAborted = 0 '\000'}

portYIELD_CORE( x ) macro is implemented to send a IPI interrupt to anthor core x (GIC SGI). The IPI_Handler is to set ulPortYieldRequired[ portGET_CORE_ID() ] = pdTRUE.

You can use this one as a reference - FreeRTOS-Kernel-Partner-Supported-Ports/TI/CORTEX_A53_64-BIT_TI_AM64_SMP at main · FreeRTOS/FreeRTOS-Kernel-Partner-Supported-Ports · GitHub

Is it possible to put a data breakpoint to catch when the task state changes to “Not Running”?

Dear @aggarg,
I am tracing task status but no progress yet. However in referencing the portable link you showed, I am confused with FreeRTOS_Tick_Handler .

In xTaskIncrementTick(), the comments point out that only core 0 does tick increment.
But this reference Tick Handler seems to be no limit only core 0 does tick increment. In my porting, it determines the number of cores firstly and only core 0 calls xTaskIncrementTick().

In this case, it is required that the application installs this ISR only for Core 0. You can see this in the corresponding demo -

1 Like

I have solved the problem, because I used xYieldPendings wrongly

Thanks for your help!

PS: I found there are some compile warning when use GCC like followed, the parameter passes to taskVALID_CORE_ID() is unsigned which is always greater than or equal to 0.

Besides, there is assert problem when runing single core. Is smp suitable for single core?

    TaskHandle_t xTaskGetCurrentTaskHandleCPU( UBaseType_t xCoreID )
    {
        TaskHandle_t xReturn = NULL;

        if( taskVALID_CORE_ID( xCoreID ) != pdFALSE )
        {
            xReturn = pxCurrentTCBs[ xCoreID ];
        }

        return xReturn;

#define taskVALID_CORE_ID( xCoreID ) ( ( BaseType_t ) ( ( 0 <= xCoreID ) && ( xCoreID < configNUM_CORES ) ) )


All these should be fixed in the latest WIP version which we plan to merge in main to have a single codebase - GitHub - chinglee-iot/FreeRTOS-Kernel at smp-dev-complete-merge-candidate-history. Can you give this one a try?

Ok, I will try it later.