I had a problem with a static assert. The static assert was exactly like this:
static_assert(std::atomic<bool>::is_always_lock_free);
and the code failed on Raspberry Pi 3 (Linux raspberrypi 4.19.118-v7+ #1311 SMP Mon Apr 27 14:21:24 BST 2020 armv7l GNU/Linux).
On the cppreference.com atomic::is_always_lock_free reference site it is stated that:
Equals true if this atomic type is always lock-free and false if it is never or sometimes lock-free. The value of this constant is consistent with both the macro ATOMIC_xxx_LOCK_FREE, where defined, with the member function is_lock_free and non-member function std::atomic_is_lock_free.
The first strange thing for me is "sometimes lock-free". What does it depend on? But questions later, back to the problem.
I made a little test. Wrote this code:
#include <iostream>
#include <atomic>
int main()
{
std::atomic<bool> dummy {};
std::cout << std::boolalpha
<< "ATOMIC_BOOL_LOCK_FREE --> " << ATOMIC_BOOL_LOCK_FREE << std::endl
<< "dummy.is_lock_free() --> " << dummy.is_lock_free() << std::endl
<< "std::atomic_is_lock_free(&dummy) --> " << std::atomic_is_lock_free(&dummy) << std::endl
<< "std::atomic<bool>::is_always_lock_free --> " << std::atomic<bool>::is_always_lock_free << std::endl;
return 0;
}
compiled and ran it on raspberry using g++ -std=c++17 atomic_test.cpp && ./a.out
(g++ 7.3.0 and 8.3.0, but that shouldn't matter) and got:
ATOMIC_BOOL_LOCK_FREE --> 1
dummy.is_lock_free() --> true
std::atomic_is_lock_free(&dummy) --> true
std::atomic<bool>::is_always_lock_free --> false
As you can see it is not as consistent as stated on the cppreference site... For comparison I ran it on my laptop (Ubuntu 18.04.5) with g++ 7.5.0 and got:
ATOMIC_BOOL_LOCK_FREE --> 2
dummy.is_lock_free() --> true
std::atomic_is_lock_free(&dummy) --> true
std::atomic<bool>::is_always_lock_free --> true
So there is a difference in ATOMIC_BOOL_LOCK_FREE
's value and of course the is_always_lock_free
constant. Looking for the definition of ATOMIC_BOOL_LOCK_FREE
all I could find is
c++/8/bits/atomic_lockfree_defines.h: #define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
c++/8/atomic: static constexpr bool is_always_lock_free = ATOMIC_BOOL_LOCK_FREE == 2;
What is the difference between ATOMIC_BOOL_LOCK_FREE
(or __GCC_ATOMIC_BOOL_LOCK_FREE
) being equal to 1 or 2? Is it a case where if 1 then it may or may not be lock-free and if 2 it is 100% lock-free? Are there any other values apart from 0? Is this an error on the cppreference site where it is stated that all those return values should be consistent? Which of the results for the raspberry pi output is really true?