# Task context switch happend between two same priority tasks with configUSE\_TIME\_SLICING=0

**URL:** <https://forums.freertos.org/t/task-context-switch-happend-between-two-same-priority-tasks-with-configuse-time-slicing-0/14478>\
**Category:** Kernel\
**Created:** [February 15, 2022, 3:52am UTC](https://forums.freertos.org/t/task-context-switch-happend-between-two-same-priority-tasks-with-configuse-time-slicing-0/14478 "2022-02-15T03:52:49Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![qwertyuiop](https://avatars.discourse-cdn.com/v4/letter/q/db5fbb/32.png) [@qwertyuiop](https://forums.freertos.org/u/qwertyuiop)\
**Post date:** [February 15, 2022, 3:52am UTC](https://forums.freertos.org/t/task-context-switch-happend-between-two-same-priority-tasks-with-configuse-time-slicing-0/14478/1 "2022-02-15T03:52:49Z")

</div>

Hi Experts,

I’m using FreeRTOS version Kernel V10.0.1 without any changes in kernel code.  
Two same priority tasks created and running, `configUSE_TIME_SLICING` was set to 0, the simple code shown as below,

```auto
prvTaskA()
{
    while(1)
    {
        printf("A");
        vTaskDelay(1);
    }
}

prvTaskB()
{
    while(1)
    {
       printf("Enter");
       while(1)
       {
            //wait 500ms
       }
       printf("Exit");
    }
}

```

In my test, between the print out info “Enter” and “Exit”, I saw a lot “A” were print out.  
From my understanding Task A has no chance to excute if Task B running state since they has the same priority and configUSE\_TIME\_SLICING = 0.

I looked into the xTaskIncrementTick function, I found below code was entered and the priority value is **Daemon timer Task** since I start a Reload timer running.

```auto
if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
{
    printf("*%d*",pxTCB->uxPriority);
    xSwitchRequired = pdTRUE;
}
else
{
     mtCOVERAGE_TEST_MARKER();
}

```

I have two questions

1. Why the code above use the pxTCB-\>uxPriority **\>=** pxCurrentTCB-\>uxPriority, It means if two task have same priority can be switched?
2. In my use case, Can I still use configUSE\_TIME\_SLICING= 0 to achieve two same priority task not switching until one task finish the processing.

Thanks  
Best Regards.

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [February 15, 2022, 3:59am UTC](https://forums.freertos.org/t/task-context-switch-happend-between-two-same-priority-tasks-with-configuse-time-slicing-0/14478/2 "2022-02-15T03:59:17Z")

</div>

To make sure I don’t misunderstand - are you saying you have a software timer that preempts the task that is sat in a null loop? If so it would be expected that both tasks run because even though you are not using time slicing the two tasks will still run in turn in between each time the timer task runs.

---

<div class="post-metadata">

**Author:** ![qwertyuiop](https://avatars.discourse-cdn.com/v4/letter/q/db5fbb/32.png) [@qwertyuiop](https://forums.freertos.org/u/qwertyuiop)\
**Post date:** [February 15, 2022, 4:57am UTC](https://forums.freertos.org/t/task-context-switch-happend-between-two-same-priority-tasks-with-configuse-time-slicing-0/14478/3 "2022-02-15T04:57:12Z")

</div>

Hi Barry,  
Thanks for your quick reponse.  
Yes, I have periodic software timer running.  
For example, I have three tasks A,B,C, Task A and Task B have the same priority, Task C is the Timer Task has the highest priority.

When Task B is running, kernel will switch to Task C if it is ready. But when Task C finished processing, it should switch back to Task B, why Task A has chance to run?

Thanks.  
Best Regards.

---

<div class="post-metadata">

**Author:** ![htibosch](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/htibosch/32/62_2.png) [@htibosch](https://forums.freertos.org/u/htibosch)\
**Post date:** [February 15, 2022, 5:29am UTC](https://forums.freertos.org/t/task-context-switch-happend-between-two-same-priority-tasks-with-configuse-time-slicing-0/14478/4 "2022-02-15T05:29:11Z")

</div>

> [@qwertyuiop](#):
>
> while(1)  
> {  
> //wait 500ms  
> }

The comment in the above code is a bit confusing. Why 500ms? Isn’t this a for ever loop like `for(;;)`?

And also: `printf()` can be a “trouble maker”, unless you have inspected its code. It may use a lot of stack space, and it may be non-reentrant. In this case, it would be safer just to increment some variables declared as volatile:

```c
unsigned task_a_loop_count = 0U;
void prvTaskA( void * pvParameters )
{
    while(1)
    {
        //printf(“A”);
        task_a_loop_count++;
        vTaskDelay(1);
    }
}

```

and inspect them during a break. Also:

```c
while(1)
{
    task_b_loop_count++;
    //wait 500ms
}

```

---

<div class="post-metadata">

**Author:** ![qwertyuiop](https://avatars.discourse-cdn.com/v4/letter/q/db5fbb/32.png) [@qwertyuiop](https://forums.freertos.org/u/qwertyuiop)\
**Post date:** [February 15, 2022, 6:03am UTC](https://forums.freertos.org/t/task-context-switch-happend-between-two-same-priority-tasks-with-configuse-time-slicing-0/14478/5 "2022-02-15T06:03:02Z")

</div>

Hi Tibosch,

Thanks for pointing out to me.  
I wrote the wrong code here, my purpose is explain Task B is always in ready state same as the code you provide.

If change the as you provide, at the begining only task\_b\_loop\_count increase, there was no change to run task A. Then high prioroity Task C preempted, Task c finished processing.  
After that task\_b\_loop\_count and task\_a\_loop\_count increased together, it means Task A and Task B run in turn.

My understanding is Task B switch to Task C, and then back to task B, since Task B and Task A have same priority and configUSE\_TIME\_SLICING = 0, so Task A will always has no chance to run.

Thanks.  
Best Regards.

---

<div class="post-metadata">

**Author:** ![qwertyuiop](https://avatars.discourse-cdn.com/v4/letter/q/db5fbb/32.png) [@qwertyuiop](https://forums.freertos.org/u/qwertyuiop)\
**Post date:** [February 15, 2022, 6:33am UTC](https://forums.freertos.org/t/task-context-switch-happend-between-two-same-priority-tasks-with-configuse-time-slicing-0/14478/6 "2022-02-15T06:33:36Z")

</div>

@rtel @htibosch  
Hi,  
Actually I have same target want to achieve as below link posted.

> [@Same priority tasks](https://forums.freertos.org/t/same-priority-tasks/12006):
>
> Hi all, I’m using freeRTOS v8 and I set: configUSE\_PREEMPTION 1 configUSE\_TIME\_SLICING 0 When I looked into the code I found this in xTaskIncrementTick(): if( pxTCB-\>uxPriority \>= pxCurrentTCB-\>uxPriority ) Now imagine we have 2 tasks with the same priority. Task A is running a lengthy computation and task B is sleeping. When the sleep time of task B expires, it seems that it will wake up and then preempt task A. That’s what I deduce from the equal sign in the condition above. What I’m …

---

<div class="post-metadata">

**Author:** ![RAc](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rac/32/1389_2.png) [@RAc](https://forums.freertos.org/u/RAc)\
**Post date:** [February 15, 2022, 6:43am UTC](https://forums.freertos.org/t/task-context-switch-happend-between-two-same-priority-tasks-with-configuse-time-slicing-0/14478/7 "2022-02-15T06:43:15Z")

</div>

> [@qwertyuiop](#):
>
> My understanding is Task B switch to Task C, and then back to task B, since Task B and Task A have same priority and configUSE\_TIME\_SLICING = 0, so Task A will always has no chance to run.

My understanding is that same priority means same priority. If you want B to deterministically be preferred over A, give B a higher priority. If two tasks have the same prio, the OS is basically free to choose whichever it grants CPU time when both are ready and have the currently highest priority.

Look at it this way: Without C or an ISR in place, the two are the highest pri players in the game and can fight it out among each other, but as soon as the scheduler comes back from something else, the cards are reshuffled.

There are other RTOSs that follow different philosophies. The now defunkt AMX, for example, treated same pri tasks as you suggested, which implies that tasks on the same priority (for example, parallel receiver tasks of several serial interfaces) must explicitly pass the baton back and forth between each other to prevent starvation. I never liked that architecture.

Don’t make assumptions. “Equal priority” means exactly that.

---

<div class="post-metadata">

**Author:** ![richard-damon](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/richard-damon/32/38_2.png) [@richard-damon](https://forums.freertos.org/u/richard-damon)\
**Post date:** [February 15, 2022, 12:07pm UTC](https://forums.freertos.org/t/task-context-switch-happend-between-two-same-priority-tasks-with-configuse-time-slicing-0/14478/8 "2022-02-15T12:07:40Z")

</div>

When Task C blocks, the schedule goes to the Highest Priority Ready Task, and the rule to break ties is the one that has been the longest since it has run, so Tasks A and B will alternate between interruptions.

configUSE\_TIME\_SLICING doesn’t force one task to keep running like you are assuming but says that ‘extra’ scheduling slots just because of the tick interrupt aren’t added. This lowers the system overhead a bit at the cost of a possibility that if nothing does happen to interrupt a task, it can starve other task of the same priority.

---

<div class="post-metadata">

**Author:** ![qwertyuiop](https://avatars.discourse-cdn.com/v4/letter/q/db5fbb/32.png) [@qwertyuiop](https://forums.freertos.org/u/qwertyuiop)\
**Post date:** [February 16, 2022, 3:43am UTC](https://forums.freertos.org/t/task-context-switch-happend-between-two-same-priority-tasks-with-configuse-time-slicing-0/14478/9 "2022-02-16T03:43:43Z")

</div>

@richard-damon @rtel  
Hi All,

Below explaination copied from  
With configUSE\_TIME\_SLICING set to 0 a context switch should not occur  
on a tick interrupt, but only when a higher priority task enters the  
Ready state, or when an interrupt other than the tick interrupt requests  
a context switch.

> [@Tasks w/ same Priority Interrupt even with time slice off](https://forums.freertos.org/t/tasks-w-same-priority-interrupt-even-with-time-slice-off/3282/3):
>
> [dnewby](https://sourceforge.net/u/dnewby/) wrote on [Wednesday, December 02, 2015](https://sourceforge.net/p/freertos/discussion/382005/thread/9336ef42/#5fb9/f3db): My sys tick interrupt occurs and it switches to task1 afterwards. Is there a configuration to set so that the same task runs before and after a context switch even if there are other tasks with the same priority? Also, if I change my tasks to print ‘1’ or ‘2’ respectively in the task loop, it prints '1’s until the systick interrupt, then '2’s, as you have said would happen. However, it never switches back to '1’s on the next systick interrupt. Why …

It mentioned a **higher** priority task enter the ready state, then a context switch will happen. It make sense to me. But now in my test if a equal priority task enter the ready state, the context switch happend as well. That’s the point I can‘t accept.

I think the related code is “if( pxTCB-\>uxPriority \>= pxCurrentTCB-\>uxPriority )” in tasks.c file casue the context switch between two same priority task. Can I change the “\>=” to “\>”, what will the issues happened, potential risk if I do this change?

Thanks.  
Best Regards.

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [February 16, 2022, 4:52am UTC](https://forums.freertos.org/t/task-context-switch-happend-between-two-same-priority-tasks-with-configuse-time-slicing-0/14478/10 "2022-02-16T04:52:51Z")

</div>

Is this the line you are referring to? [https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/tasks.c#L2832](https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/tasks.c#L2832) - there a context switch is triggered by another task’s block period expired, rather than just because there is a tick interrupt. Setting configUSE\_TIMESLICING to 0 prevents this line from executing: [https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/tasks.c#L2853](https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/tasks.c#L2853), which would otherwise trigger a context switch on every tick interrupt - the tick interrupt marking the end of the time slice.

Arguably the first linked line could be “greater than” rather than “greater than or equal to” as it will cause a context switch to a task that just left the blocked state, which you would prevent by setting configUSE\_PREEMPTION to 0, but its not a context switch cause by the end of the running task’s time slice.
