FreeRTOS / FreeRTOS-Kernel

FreeRTOS kernel files only, submoduled into https://github.com/FreeRTOS/FreeRTOS and various other repos.

Home Page:https://www.FreeRTOS.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[BUG] Atomic_*s are not atomic!

sebunger opened this issue · comments

In atomic.h, ATOMIC_ENTER_CRITICAL and ATOMIC_EXIT_CRITICAL are defined differently depending on whether portSET_INTERRUPT_MASK_FROM_ISR is defined! However, in FreeRTOS.h this macro is stubbed out if it is not already defined by the port.

This means that on all ports that do not, in fact, define their own (and functional) portSET_INTERRUPT_MASK_FROM_ISR, the atomics will end up silently not being atomic resulting in who-knows-what sort of bugs.

This is particularly egregious since the template port does not even mention that macro in its template portmacro.h!

There’s a possibly related but not quite identical post that dates back 7 years. So this may have been there a while? Unfortunately I can’t seem to link to the post since I just signed up, but the topic number is 6295.

There's a bit more discussion along with possible avenues for fixes in the forum: https://forums.freertos.org/t/atomic-s-are-not-atomic/18809

I did a quick test with MSP430. That port does not define portSET_INTERRUPT_MASK_FROM_ISR(). I added some code to call Atomic_Increment_u32() and then checked the compiled code (asm file produced by compiler). The compiled code does not mask interrupts and does not provide atomic behavior. So this is a good catch.

From the forum post it seems adding a new symbol portHAS_NESTED_INTERRUPTS would allow a simple fix to atomic.h.

@sebunger
Thank you for reporting this issue. This issue is addressed in PR #940.
Feel free to reopen this issue for further problem about this issue.