I have two questions:
- In the general case is it safe to use an atomic as a T and switch between them interchangeably?
- In the case of a futex is it safe to do the cast?
I am aware that performing atomic operations on non-atomic types is undefined behaviour but I cannot find an answer for the reverse. For example, this which compiles and executes as expected:
std::atomic_int foo = 5;
int* bar = reinterpret_cast<int*>(&foo);
(*bar)++;
std::cout << (*bar) << std::endl;
As to the second question, the Linux manpage says in the FUTEX_WAIT operation
The load of the value of the futex word is an atomic memory access (i.e., using atomic machine instructions of the respective architecture). This load, the comparison with the expected value, and starting to sleep are performed atomically and totally ordered with respect to other futex operations on the same futex word.
So is the following code safe?
std::atomic_int32_t val = 0;
syscall(SYS_futex, reinterpret_cast<int*>(&val), FUTEX_WAIT_PRIVATE, 0, nullptr);