Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT Training


Concerns about the atomicity of vTaskSuspendAll()

Posted by kilo-sierra on September 17, 2013

~~~~~~ vTaskSuspendAll() ~~~~~~ is used to lock taskswitches without disabling interrupts. Pretty good. But this function works by just incrementing a global variable ~~~~~~ ++uxSchedulerSuspended; ~~~~~~ On many platforms including AVR and ARM Cortex M this operation compiles to something like

~~~~~~ load uxSchedulerSuspendeded into register increment register store register into uxSchedulerSuspendeded ~~~~~~

which is obviously NOT ATOMIC.

Therefore the variable uxSchedulerSuspendeded may get a wrong value which can lead to unintended unlocking of the kernel with catastrophic consequences.

I suggest to modify the locking function like this

~~~~~~ void vTaskSuspendAll( void ) { portATOMIC_INCREMENT( uxSchedulerSuspended); } ~~~~~~

and to implement a macro portATOMIC_INCREMENT() for all platforms that lack an atomic increment machine instruction.

Concerns about the atomicity of vTaskSuspendAll()

Posted by destremps on September 18, 2013

Well he sure might be right. I suppose there is only such a thing as an atomic read. Not an atomic read-increment-write to a global. Native size or not. Does this need to be fixed?

Concerns about the atomicity of vTaskSuspendAll()

Posted by jdurand on September 18, 2013

When I modify globals I use something like this

~~~~ void FlagClear(int i) { // safely clear a flag vPortEnterCritical(); // disable FreeRTOS interrupts Flags &= ~i; // clear the flag vPortExitCritical(); // put interrupts back like they were } ~~~~

Of course that has the problem of Enter and Exit not working right...

Concerns about the atomicity of vTaskSuspendAll()

Posted by richardbarry on September 18, 2013

Sorry not to answer this sooner - I've been thrown out somewhat by the forum software being updated and then having to re-register to get notifications of people posting.

This topic has been discussed a few times, you should be able to find it in the archive on the FreeRTOS.org website.

Basically the key to this is that each task maintains its own context, and a context switch cannot occur if the variable is non zero. So, as long as the writing from the register back into the memory is atomic, it is not a problem.

In your example, consider the following scenario, which starts with uxSchedulerSuspended at zero.

/* This load stores the variable's value in a register. */
load uxSchedulerSuspendeded into register

 ... Now a context switch causes another task to run, and
the other task uses the same variable.  The other task 
will see the variable as zero because the variable has 
not yet been updated by the original task... Eventually 
the original task runs again.  **That can only happen 
when uxSchedulerSuspended is once again zero**, and when 
the original task runs again the contents of the CPU 
registers are restored to exactly how they were when it 
was switched out - therefore the value it read into the 
register still matches the value of the 
xuSchedulerSuspended variable ... 

/* The value will be incremented to be equal to 1. */
increment register

/* The value restored to uxSchedulerSuspended will be the 
correct value of 1, even though the variable was used 
by other tasks in the mean time. */
store register into uxSchedulerSuspendeded


Concerns about the atomicity of vTaskSuspendAll()

Posted by destremps on September 18, 2013

Thanks Richard. Okay. That explains it. This particular variable 'self protects' itself.

Concerns about the atomicity of vTaskSuspendAll()

Posted by kilo-sierra on September 18, 2013

YUP - got it ... good news! uxSchedulerSuspended is binary, not counting because of it's special use. Especially it is not used whithin one of the ..fromISR functions. So everything is fine.

Thank you Richard!

[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]

Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.

Free TCP/IP and file system demos for the RTOS

Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑

FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists