1 // Copyright (c) 2011 Helge Bahmann
3 // Distributed under the Boost Software License, Version 1.0.
4 // See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
7 // Verify that definition of the "LOCK_FREE" macros and the
8 // "is_lock_free" members is consistent and matches expectations.
9 // Also, if any operation is lock-free, then the platform
10 // implementation must provide overridden fence implementations.
12 #include <boost/atomic.hpp>
15 #include <boost/config.hpp>
16 #include <boost/core/lightweight_test.hpp>
18 static const char * lock_free_level
[] = {
26 verify_lock_free(const char * type_name
, int lock_free_macro_val
, int lock_free_expect
)
28 BOOST_TEST(lock_free_macro_val
>= 0 && lock_free_macro_val
<= 2);
29 BOOST_TEST(lock_free_macro_val
== lock_free_expect
);
31 boost::atomic
<T
> value
;
33 if (lock_free_macro_val
== 0)
34 BOOST_TEST(!value
.is_lock_free());
35 if (lock_free_macro_val
== 2)
36 BOOST_TEST(value
.is_lock_free());
38 BOOST_TEST(boost::atomic
<T
>::is_always_lock_free
== (lock_free_expect
== 2));
40 std::cout
<< "atomic<" << type_name
<< "> is " << lock_free_level
[lock_free_macro_val
] << " lock free\n";
43 #if (defined(__GNUC__) || defined(__SUNPRO_CC)) && defined(__i386__)
45 #define EXPECT_CHAR_LOCK_FREE 2
46 #define EXPECT_SHORT_LOCK_FREE 2
47 #define EXPECT_INT_LOCK_FREE 2
48 #define EXPECT_LONG_LOCK_FREE 2
49 #if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B)
50 #define EXPECT_LLONG_LOCK_FREE 2
52 #define EXPECT_LLONG_LOCK_FREE 0
54 #define EXPECT_INT128_LOCK_FREE 0
55 #define EXPECT_POINTER_LOCK_FREE 2
56 #define EXPECT_BOOL_LOCK_FREE 2
58 #elif (defined(__GNUC__) || defined(__SUNPRO_CC)) && defined(__x86_64__)
60 #define EXPECT_CHAR_LOCK_FREE 2
61 #define EXPECT_SHORT_LOCK_FREE 2
62 #define EXPECT_INT_LOCK_FREE 2
63 #define EXPECT_LONG_LOCK_FREE 2
64 #define EXPECT_LLONG_LOCK_FREE 2
65 #if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) && (defined(BOOST_HAS_INT128) || !defined(BOOST_NO_ALIGNMENT))
66 #define EXPECT_INT128_LOCK_FREE 2
68 #define EXPECT_INT128_LOCK_FREE 0
70 #define EXPECT_POINTER_LOCK_FREE 2
71 #define EXPECT_BOOL_LOCK_FREE 2
73 #elif defined(__GNUC__) && (defined(__POWERPC__) || defined(__PPC__))
75 #define EXPECT_CHAR_LOCK_FREE 2
76 #define EXPECT_CHAR16_T_LOCK_FREE 2
77 #define EXPECT_CHAR32_T_LOCK_FREE 2
78 #define EXPECT_WCHAR_T_LOCK_FREE 2
79 #define EXPECT_SHORT_LOCK_FREE 2
80 #define EXPECT_INT_LOCK_FREE 2
81 #define EXPECT_LONG_LOCK_FREE 2
82 #if defined(__powerpc64__)
83 #define EXPECT_LLONG_LOCK_FREE 2
85 #define EXPECT_LLONG_LOCK_FREE 0
87 #define EXPECT_INT128_LOCK_FREE 0
88 #define EXPECT_POINTER_LOCK_FREE 2
89 #define EXPECT_BOOL_LOCK_FREE 2
91 #elif defined(__GNUC__) && defined(__alpha__)
93 #define EXPECT_CHAR_LOCK_FREE 2
94 #define EXPECT_CHAR16_T_LOCK_FREE 2
95 #define EXPECT_CHAR32_T_LOCK_FREE 2
96 #define EXPECT_WCHAR_T_LOCK_FREE 2
97 #define EXPECT_SHORT_LOCK_FREE 2
98 #define EXPECT_INT_LOCK_FREE 2
99 #define EXPECT_LONG_LOCK_FREE 2
100 #define EXPECT_LLONG_LOCK_FREE 2
101 #define EXPECT_INT128_LOCK_FREE 0
102 #define EXPECT_POINTER_LOCK_FREE 2
103 #define EXPECT_BOOL_LOCK_FREE 2
105 #elif defined(__GNUC__) &&\
107 defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) ||\
108 defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) ||\
109 defined(__ARM_ARCH_6ZK__) ||\
110 defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) ||\
111 defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) ||\
112 defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7S__)\
115 #define EXPECT_CHAR_LOCK_FREE 2
116 #define EXPECT_SHORT_LOCK_FREE 2
117 #define EXPECT_INT_LOCK_FREE 2
118 #define EXPECT_LONG_LOCK_FREE 2
119 #if !(defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6Z__)\
120 || ((defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__)) && defined(__thumb__)) || defined(__ARM_ARCH_7M__))
121 #define EXPECT_LLONG_LOCK_FREE 2
123 #define EXPECT_LLONG_LOCK_FREE 0
125 #define EXPECT_INT128_LOCK_FREE 0
126 #define EXPECT_POINTER_LOCK_FREE 2
127 #define EXPECT_BOOL_LOCK_FREE 2
129 #elif defined(__linux__) && defined(__arm__)
131 #define EXPECT_CHAR_LOCK_FREE 2
132 #define EXPECT_SHORT_LOCK_FREE 2
133 #define EXPECT_INT_LOCK_FREE 2
134 #define EXPECT_LONG_LOCK_FREE 2
135 #define EXPECT_LLONG_LOCK_FREE 0
136 #define EXPECT_INT128_LOCK_FREE 0
137 #define EXPECT_POINTER_LOCK_FREE 2
138 #define EXPECT_BOOL_LOCK_FREE 2
140 #elif (defined(__GNUC__) || defined(__SUNPRO_CC)) && (defined(__sparcv8plus) || defined(__sparc_v9__))
142 #define EXPECT_CHAR_LOCK_FREE 2
143 #define EXPECT_SHORT_LOCK_FREE 2
144 #define EXPECT_INT_LOCK_FREE 2
145 #define EXPECT_LONG_LOCK_FREE 2
146 #define EXPECT_LLONG_LOCK_FREE 2
147 #define EXPECT_INT128_LOCK_FREE 0
148 #define EXPECT_POINTER_LOCK_FREE 2
149 #define EXPECT_BOOL_LOCK_FREE 2
151 #elif defined(BOOST_USE_WINDOWS_H) || defined(_WIN32_CE) || defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
153 #define EXPECT_CHAR_LOCK_FREE 2
154 #define EXPECT_SHORT_LOCK_FREE 2
155 #define EXPECT_INT_LOCK_FREE 2
156 #define EXPECT_LONG_LOCK_FREE 2
157 #if defined(_WIN64) || defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) || defined(_M_AMD64) || defined(_M_IA64) || (_MSC_VER >= 1700 && (defined(_M_ARM) || defined(_M_ARM64)))
158 #define EXPECT_LLONG_LOCK_FREE 2
160 #define EXPECT_LLONG_LOCK_FREE 0
162 #define EXPECT_INT128_LOCK_FREE 0
163 #define EXPECT_POINTER_LOCK_FREE 2
164 #define EXPECT_BOOL_LOCK_FREE 2
168 #define EXPECT_CHAR_LOCK_FREE 0
169 #define EXPECT_SHORT_LOCK_FREE 0
170 #define EXPECT_INT_LOCK_FREE 0
171 #define EXPECT_LONG_LOCK_FREE 0
172 #define EXPECT_LLONG_LOCK_FREE 0
173 #define EXPECT_INT128_LOCK_FREE 0
174 #define EXPECT_POINTER_LOCK_FREE 0
175 #define EXPECT_BOOL_LOCK_FREE 0
179 int main(int, char *[])
181 verify_lock_free
<char>("char", BOOST_ATOMIC_CHAR_LOCK_FREE
, EXPECT_CHAR_LOCK_FREE
);
182 verify_lock_free
<short>("short", BOOST_ATOMIC_SHORT_LOCK_FREE
, EXPECT_SHORT_LOCK_FREE
);
183 verify_lock_free
<int>("int", BOOST_ATOMIC_INT_LOCK_FREE
, EXPECT_INT_LOCK_FREE
);
184 verify_lock_free
<long>("long", BOOST_ATOMIC_LONG_LOCK_FREE
, EXPECT_LONG_LOCK_FREE
);
185 #ifdef BOOST_HAS_LONG_LONG
186 verify_lock_free
<long long>("long long", BOOST_ATOMIC_LLONG_LOCK_FREE
, EXPECT_LLONG_LOCK_FREE
);
188 #ifdef BOOST_HAS_INT128
189 verify_lock_free
<boost::int128_type
>("int128", BOOST_ATOMIC_INT128_LOCK_FREE
, EXPECT_INT128_LOCK_FREE
);
191 verify_lock_free
<void *>("void *", BOOST_ATOMIC_POINTER_LOCK_FREE
, EXPECT_SHORT_LOCK_FREE
);
192 verify_lock_free
<bool>("bool", BOOST_ATOMIC_BOOL_LOCK_FREE
, EXPECT_BOOL_LOCK_FREE
);
195 BOOST_ATOMIC_CHAR_LOCK_FREE
> 0 ||
196 BOOST_ATOMIC_SHORT_LOCK_FREE
> 0 ||
197 BOOST_ATOMIC_INT_LOCK_FREE
> 0 ||
198 BOOST_ATOMIC_LONG_LOCK_FREE
> 0 ||
199 BOOST_ATOMIC_LLONG_LOCK_FREE
> 0 ||
200 BOOST_ATOMIC_BOOL_LOCK_FREE
> 0;
202 BOOST_TEST(!any_lock_free
|| BOOST_ATOMIC_THREAD_FENCE
> 0);
204 return boost::report_errors();