Does the same priority task will happen preemption?

Hi , i have a question about the Freertos task scheduling.

There are 2 task which priority is same and it is single core , as we know the kernel will prepare a time slice for every task .

And i am so wonder that is that possible when the task A had not finish its job and timeout happen ?
does the kernel will switch the context and make task B running? or keep the state until Task A finish its job ?

if task A and Task B were always operated the same queue ,which i mean that they will call the same API to push the data into the same queue.(and this API is without mutex operation)

is that possible sometimes when Task A push the data1 into queue location1 in half way ,and kernel time slice is timeout,and kernel switch context to Task B,
and then Task B doing the same push action (push data2 into queue location1) 。。。。

after that ABA issue happens!!!!

BR!

FreeRTOS will use a critical section to make the copying of the data into the queue an atomic operation, so you won’t have a problem. The copying of the queue data is quick enough, FreeRTOS chooses to use a Critical Section (which disable interrupt for a short while) instead of a Mutex, and trying to use a mutex wouldn’t work to allow ISRs to push data onto queues, which is an important use of them.

1 Like

Hi @sxl808, Welcome to the FreeRTOS Community !

Yes, this will happen if you have set configUSE_TIME_SLICING to 1 so the scheduler will switch between equal priority tasks on each tick interrupt, and in your case task B will start running.

If you want to read more about different types of FreeRTOS task scheduling, you can go through this section of the book FreeRTOS-Kernel-Book/ch04.md at main · FreeRTOS/FreeRTOS-Kernel-Book · GitHub

For your 2nd question, I agree completely with @richard-damon.

1 Like

Hi Rohitmdn & Richard :
thank you for your reply first.
But i have not got the point !
As you said it is possible that switching action will be happen in this case (two same priority task). how does Freertos make sure copy data action will not be interrupt?

So let me show the sample code with you !

 static void pushMsgQueue(c_msgQueue *MsgQueue, UINT32 msgType, UINT32 size, UINT8 *msgData)
{
     UINT8 Temp = 0;
     if (isMsgQueueFull(MsgQueue) == QUEUE_IS_FULL)
     {
         return MSG_FAIL;
     }
     Temp = MsgQueue->MsgQueueTear;
     MsgQueue->MsgNode[Temp].MsgType = msgType;
     MsgQueue->MsgNode[Temp].ParamerLen = size;
     memset(MsgQueue->MsgNode[Temp].Data,0,MSG_DATA_TOTAL);
     memcpy(MsgQueue->MsgNode[Temp].Data,msgData,(UINT32)size);
     Temp++;

     MsgQueue->MsgQueueTear = Temp;
}
------------------------------------------------------------------
void Task1_Entry( void *p_arg ) 
{ 
   for ( ;; ) 
   { 
	processs_event1();
	processs_event2();
            ...
    pushMsgQueue(target_Queue, A, 5, data1); 
  } 
} 


void Task2_Entry( void *p_arg ) 
{ 
    for ( ;; ) 
    { 
        pushMsgQueue(target_Queue, B, 5, data2);  
    } 
}

Just like that ,

  1. there are only two task, Taks1 and Task2
  2. their priority is same ,
  3. Task1 will do so many process,and the last one is call pushMsg API to send the data into the target queue .
  4. Task2 only doing the pushMsg action.

my question is Whether there is a moment:

  1. when Task1 being push action (etc, maybe the code is Executive at “MsgQueue->MsgNode[Temp].MsgType = msgType;” and the Tear is 5)

  2. and it is timeout to switching to the Task2, and then Task2 doing the Push action and send the data2 into the Queue.

  3. when kernel switch back to Task1 , it will continue its push action

  4. So the ABA issue happen in the MsgNode[5]
    MsgNode[5].MsgType = A ----------》Task1 timeout

MsgNode[5].MsgType = B ----------》 switching Task2
MsgNode[5].data = data2 ----------》 switching Task2

MsgNode[5].MsgType = A ----------》 switch back to Task1
MsgNode[5].data = data1 ----------》 switch back to Task1

BR!

Hi Richard :
Thanks!
Do you mean i need to add so code in the Push data action ,just like :

 void  push-data()
 {
     taskENTER_CRITICAL();
     push_data_action();
     taskEXIT_CRITICAL();
 }

but if there isn’t those operation,is that means what I’m worried about(ABA issue) is possible happen in two same priority?

BR!

Looking at the code you shared, it seems like you are using a custom queue implementation instead of FreeRTOS queues. If that’s the case, your description is correct—a context switch can occur between the execution of the pushMsgQueue function.

FreeRTOS ensures data copying is not interrupted by temporarily disabling interrupts when performing critical operations. The xQueueSend() API, for example, internally uses taskENTER_CRITICAL() and taskEXIT_CRITICAL() to protect critical sections.

I recommend using FreeRTOS queues instead of a custom implementation. FreeRTOS provides robust queue management APIs such as xQueueCreate() and xQueueSend() to handle data safely and efficiently. You can refer to the Queue Management documentation for a complete list of available queue-related APIs.

void push_data()  
{  
    taskENTER_CRITICAL();  
    push_data_action();  
    taskEXIT_CRITICAL();  
}  

As you shared, If you still need to ensure that a specific data operation is not preempted, you can explicitly disable and re-enable interrupts around it:
This approach ensures that no context switch occurs while push_data_action() executes.

1 Like

FreeRTOS, in its queue functions, does basically that, the actual operations that manipulate the data are inside a critical section, so the operation can’t be interrupts.

If your “push_data_action” uses a FreeRTOS queue, then it will deal with the issue. If you are manipulating data objects yourself, then you need to deal with it.

You could use a critical section around the manipulation, and if the data might be also manipulated inside an ISR, that tends to be the way to do it. (Just be careful about making the critical section too long). If you don’t need to worry about an ISR, then longer periods can be done either by suspending the scheduler, or using a Mutex. The Mutex will cost a little bit of memory, but is the finest grained operation.

1 Like

If this your custom queue implementation or are your trying to show what FreeRTOS queues might be doing? If later, as explained by @rohitmdn and @richard-damon, FreeRTOS adds critical sections to ensure that the data corruptions cannot happen.

1 Like