# EnterCritical and volatile

**URL:** <https://forums.freertos.org/t/entercritical-and-volatile/12303>\
**Category:** Kernel\
**Created:** [April 13, 2021, 9:59pm UTC](https://forums.freertos.org/t/entercritical-and-volatile/12303 "2021-04-13T21:59:19Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rik001](https://avatars.discourse-cdn.com/v4/letter/r/bbce88/32.png) [@Rik001](https://forums.freertos.org/u/Rik001)\
**Post date:** [April 13, 2021, 9:59pm UTC](https://forums.freertos.org/t/entercritical-and-volatile/12303/1 "2021-04-13T21:59:19Z")

</div>

Hi,  
I just wanted to make sure that the enter critical is only relevant when a variable is accessed/changed by ISR and not when it is accessed/changed by other tasks. That is because - when doing context switching - freeRTOS takes care of completing any variables reading/mods that are not atomic in order to save a “stable” value to the stack before the context switch.

Is that correct?

Or does the freeRTOS scheduler, being obviously controlled by interrupt/s, just switches regardless of where it is including if it is in the middle of changing a variable of size different than the platform basic type/width?

Also, and kid of related… in cases where a variable can be changed by multiple tasks does volatile need to be used?

Thank you

---

<div class="post-metadata">

**Author:** ![n9wxu](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/n9wxu/32/1391_2.png) [@n9wxu](https://forums.freertos.org/u/n9wxu)\
**Post date:** [April 13, 2021, 11:10pm UTC](https://forums.freertos.org/t/entercritical-and-volatile/12303/2 "2021-04-13T23:10:18Z")

</div>

Sorry, that is not correct.  
If FreeRTOS is configured for preemptive multitasking, the switch occurs on an interrupt. The interrupt can occur at any point in the update of a variable including a partial update.  
The possibility of a partial update depends heavily upon the data type of the variable and the CPU architecture you are using but the partial updates can happen in ways that you were not expecting.

If you want to be sure that your variable is being read while its data is valid you must either wrap that variable with a mutex or use taskENTER\_CRITICAL and taskEXIT\_CRITICAL to prevent interrupts and context switches while the update is happening.

> **[This page describes the FreeRTOS taskENTER\_CRITICAL() and taskEXIT\_CRITICAL()...](https://www.freertos.org/taskENTER_CRITICAL_taskEXIT_CRITICAL.html)**
>
> Using xTaskCreateStatic() to create an RTOS task using statically allocated memory.

For added fun and practice with critical sections play deadlock empire

> **[The Deadlock Empire](https://deadlockempire.github.io/)**
>
> Slay dragons, learn
> concurrency! Play the cunning Scheduler, exploit flawed
> programs and defeat the armies of the Parallel Wizard.

---

<div class="post-metadata">

**Author:** ![hs2](https://avatars.discourse-cdn.com/v4/letter/h/a4c791/32.png) [@hs2](https://forums.freertos.org/u/hs2)\
**Post date:** [April 13, 2021, 11:12pm UTC](https://forums.freertos.org/t/entercritical-and-volatile/12303/3 "2021-04-13T23:12:55Z")

</div>

It’s the sole purpose of a preemptive scheduler to preempt an executing thread or task at any point. There is no magic completion of some actions or code of the task which is preempted. The scheduler isn’t and can’t be aware of the meaning of the code which was currently executed on preemption.  
Be warned that you should know exactly what you’re doing when sharing task stack variables e.g. by sending their address/pointer to another task.  
Better start with sharing global variables. Even better avoid it 😉  
Please see the C/C++ standard or the net for the definition and meaning of the C/C++ keyword `volatile`.  
Simple resp. CPU native variables (e.g. a 32 bit integer on a 32 bit MCU) can be shared atomically by declaring them `volatile` (read: this variable might get changed from outside the current code known to the compiler).  
On the other hand there are atomic standard data types provided by recent compilers supporting newer C/C++ standards (C/C++11).  
Complex data structures a might be protected by mutexes or critical sections. That’s their purpose and the reason why every multitasking OS comes with mutexes and often with critical sections.
