In an embedded (ARM) environment with no OS, if I use interrupts, then is there potential for deadlock using std::atomic<T>
? If so, how?
In general, any moment, control can be interrupted to handle an interrupt. In particular, if one were to naively have a mutex and wanted to use it to do a "safe" to a variable, one might lock it, write, and unlock and then elsewhere lock, read, and unlock. But if the read is in an interrupt, you could lock, interrupt, lock => deadlock.
In particular, I have a std::atomic<int>
for which is_always_lock_free
is false
. Should I worry about the deadlock case? When I look at the generated assembly, writing 42
looks like:
bl __sync_synchronize
mov r3, #42
str r3, [sp, #4]
bl __sync_synchronize
which doesn't appear to be locking. The asm for reading the value is similar. Is the (possible) lock for the fancier operations like exchange
?
std::atomic. Each instantiation and full specialization of the std::atomic template defines an atomic type. If one thread writes to an atomic object while another thread reads from it, the behavior is well-defined (see memory model for details on data races).
Atomic variable examples In order to use atomicity in your program, use the template argument std::atomic on the attributes. Note, that you can't make your whole class atomic, just it's attributes. }; You don't need to use volatile along with std::atomic .
atomic<T> variables don't use locks (at least where T is natively atomic on your platform), but they're not lock-free in the sense above. You might use them in the implementation of a lock-free container, but they're not sufficient on their own.
__sync_synchronize
is just a builtin for a full memory barrier. There is no locking involved, so no potential for deadlock as there would be with a mutex and interrupt handler.
What ARM core are you using? On an ARM Cortex-A7 the following prints true
for both.
#include <iostream>
#include <atomic>
int main()
{
std::atomic<int> x;
std::cout << std::boolalpha << x.is_lock_free() << std::endl;
std::cout << std::atomic<int>::is_always_lock_free << std::endl;
}
I would expect std::atomic<int>
to be implemented without locks most if not all on ARM, and certainly from the assembly you provided it does not appear to be using a lock.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With