atomic : is_lock_free

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//I can not get the significance of 'is_lock_free'
#define _ENABLE_ATOMIC_ALIGNMENT_FIX
#include  <atomic>
#include <iostream>
#include <string>
#include <type_traits>
class A
{
	int a;
	int b;
};
int main()
{
	std::atomic_char ac;
	std::atomic<A> aa;
	std::atomic<unsigned long long> aull;
	std::cout << std::boolalpha;
	//all are true
	std::cout << ac.is_lock_free()   << std::endl;//true
	std::cout << aa.is_lock_free()   << std::endl;//true
	std::cout << aull.is_lock_free() << std::endl;//true
	std::cin.get();
}

is_lock_free() evaluates to true if atomic operations on the type are lock-free.

In simplified terms, this means that lock-free atomic CPU instructions are used to enforce atomicity (no secondary locking mechanisms like mutexes are involved).
can give a 'false' example?
the is_lock_free()'s result is false?
> can give a 'false' example?

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <utility>
#include <atomic>

int main()
{
    struct A { int i = 0 ; double d = 9 ; char c[100] {} ; };
    
    std::cout << "    A is trivially copyable? " << std::boolalpha << std::is_trivially_copyable<A>::value << '\n' // true
              << "std::atomic<A> is lock free? " << std::boolalpha << std::atomic<A>{}.is_lock_free() << '\n' ; // false
}

http://coliru.stacked-crooked.com/a/78f0417a5f8dbbed
http://rextester.com/QAJ28098

Note: clang++/libc++ and g++/libstdc++ on Linux have dependency on libatomic. (Need to link with -latomic.)
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#define _ENABLE_ATOMIC_ALIGNMENT_FIX
#include <iostream>
#include <utility>
#include <atomic>
struct A1
{
	long long i : 32;
	long long j : 32;
};
struct A2
{
	long long i : 32;
	long long j : 32;
	long long k : 1;
};
int main()
{
	//on window10, vs2015

	//64 bit is the standard?
	std::cout << std::boolalpha;
	std::cout << "std::atomic<A1>{}.is_lock_free():" << std::atomic<A1>{}.is_lock_free() << ";sizeof(A1):" << sizeof(A1) << std::endl;
	std::cout << "std::atomic<A2>{}.is_lock_free():" << std::atomic<A2>{}.is_lock_free() << ";sizeof(A2):" << sizeof(A2) << std::endl;
	std::cin.get();
}
> 64 bit is the standard?

No.

What can be atomic lock-free depends on the processor architecture
(in practice it depends on both the size and the alignment of the trivially copyable atomic object).

The subset of what is actually atomic lock-free depends on the quality of implementation
note: the C++ standard does not require that sizeof( std::atomic<T> ) must be equal to sizeof(T)

libc++ (FreeBSD)
1
2
3
static inline bool __c11_atomic_is_lock_free(size_t __size) {
    return __atomic_is_lock_free(__size, 0);
}

https://svnweb.freebsd.org/base/release/10.3.0/contrib/libc%2B%2B/include/atomic?revision=297553&view=markup#l626
1
2
3
4
5
6
7
8
9
10
struct __atomic_base  // false
{
    // ...
    bool is_lock_free() const volatile _NOEXCEPT
    {return __c11_atomic_is_lock_free(sizeof(_Tp));}
    // ...
    bool is_lock_free() const _NOEXCEPT
    {return __c11_atomic_is_lock_free(sizeof(_Tp));}
    // ...
};

https://svnweb.freebsd.org/base/release/10.3.0/contrib/libc%2B%2B/include/atomic?revision=297553&view=markup#l814

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <atomic>
#include <iomanip>

template < std::size_t N > void test() 
{
    struct A { char c[N] {} ; } ;
    std::cout << std::setw(6) << sizeof(A) << std::setw(15)  << sizeof( std::atomic<A> ) 
              << "                  " << std::atomic<A>{}.is_lock_free() << '\n' ;
}

int main()
{
    std::cout << "sizeof(T)   sizeof( std::atomic<T> ) is_lock_free\n" 
              << "-------------------------------------------------\n\n" << std::boolalpha ;
              
    test<3>() ;
    test<4>() ;
    
    test<5>() ;
    test<8>() ;
    
    test<9>() ;
    test<16>() ;
}

-------- clang++/libc++ --------


sizeof(T)   sizeof( std::atomic<T> ) is_lock_free
-------------------------------------------------

     3              4                  true
     4              4                  true
     5              8                  true
     8              8                  true
     9             16                  false
    16             16                  true

-------- g++/libstdc++ --------


sizeof(T)   sizeof( std::atomic<T> ) is_lock_free
-------------------------------------------------

     3              3                  false
     4              4                  true
     5              5                  false
     8              8                  true
     9              9                  false
    16             16                  true 

http://coliru.stacked-crooked.com/a/3163e75f372c1ba7

Hmm.... clang++ pads up size 9 to size 16, and then turns around and says that it is not lock-free.
Thanks. It is so complex!
Topic archived. No new replies allowed.