Atomic variable for scheduler question
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-03-07 8:19 AM
I traditionally use a volatile type for my schedulers. Very simple like so
volatile uint8_t myflag;
uint8_t ticks;
void Func(void){
++ticks;
if(!(ticks % 5)){
myflag = true;
}
}
void User(void){
if(myflag) {
myflag = false;
//DO Something
}
}
I'm trying to update my knowledge. The online thought seems to be that this isn't really the safe way as this does not have any memory barrier. So the proper way is to use an atomic. So I tried an atomic.
atomic_bool myflag = ATOMIC_VAR_INIT(false);
uint8_t ticks;
void Func(void){
++ticks;
if(!(ticks % 5)){
atomic_store(&myflag ,true);
}
}
void User(void){
if(atomic_load(&myflag)) {
atomic_store(&myflag ,false);
//DO Something
}
}
However, this definitely does not work. The User misses flag settings regularly. Its not just a delay. But per the scope its like a complete flag setting is missed. What have I done wrong here? I even tried to make it volatile and also tried atomic_flag but they both miss settings but the old school way does not miss any settings.
- Labels:
-
Interrupt
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-03-09 1:59 PM
Ok, maybe I am too dumb but what exactly kind of synchronization is needed for bool variable access which is not modified (so no RMW access), just set, reset or tested?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-03-09 2:49 PM
What do you mean by "not modified"? The bool in my example is modified by both processes.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-03-09 3:11 PM
No, it is not modified. It is set to 0 or to 1. So, what would "locking" or "atomic access" change? It could maybe be needed if the numeric variable was incremented or decremented, but it is not.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-03-09 3:15 PM
Per your definition, no boolean ever needs synchronization. Correct?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-03-09 4:04 PM
Not if it is always set by one party and cleared by another (one only).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-03-09 4:24 PM
Are you being pedantic about the term "synchronization"? Because clearly in multithreaded environments you need to ensure changes made by one thread are seen by another with some deterministic sequence and timing.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-03-09 11:42 PM - edited ‎2025-03-10 12:37 AM
Right, but 1. this is not related to "atomicity" and 2. does not apply to physically single-core and single-threaded microcontroller.
With a single-core, single-threaded microcontroller, you would encounter the problem if a variable of a numeric type was incremented/decremented by two or more pieces of code in two or more threads or a thread and ISR. AFAIK, this is not the case we are discussing here.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-03-10 7:57 AM
I think you are taking this term Atomicity to only refer to corrupting the value but there is more to it than that.
If you look at the standard concurrency example of two threads incrementing a number there are 2 issues.
1. A non-atomic sized number can get torn into a nonsense number. e.g. a 16-bit number incrementing on an 8-bit MCU.
2. Out of sequence increment causing increments to be lost/overwritten.
For this 1bit scenario the concern is only #2. Values being lost. As soon as you introduce IRQs you create this problem. Even on single core single threaded mcu.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-03-10 8:21 AM
Right, BUT NOT FOR BOOLEAN SET & RESET.
In ARM-M architecture the problem appears when you modify a 64-bit number.
It also appears when any-size the value is modified (arithmetic or logic operation) by low priority code and tested by high priority code.
It could appear during boolean operations on memory variables - and/or/xor/not, cause they are not atomic at hardware level.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-03-10 8:23 AM
True for #1 but what about issue #2?
