Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is std::atomic<T> safe with interrupts when std::atomic<T>::is_always_lock_free is false?

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?

like image 268
Ben Avatar asked Jun 12 '18 15:06

Ben


People also ask

What does std :: atomic do?

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).

Does STD Atomic need volatile?

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 .

Is atomic lock free?

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.


1 Answers

__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.

like image 183
rmawatson Avatar answered Sep 18 '22 03:09

rmawatson