• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <boost/config.hpp>
2 
3 //  atomic_sp_test.cpp
4 //
5 //  Copyright 2008, 2017 Peter Dimov
6 //
7 //  Distributed under the Boost Software License, Version 1.0.
8 //  See accompanying file LICENSE_1_0.txt or copy at
9 //  http://www.boost.org/LICENSE_1_0.txt
10 
11 
12 #include <boost/smart_ptr/atomic_shared_ptr.hpp>
13 #include <boost/core/lightweight_test.hpp>
14 #include <boost/memory_order.hpp>
15 
16 //
17 
18 struct X
19 {
20 };
21 
22 #define BOOST_TEST_SP_EQ( p, q ) BOOST_TEST( p == q && !( p < q ) && !( q < p ) )
23 
main()24 int main()
25 {
26     // default constructor
27 
28     {
29         boost::atomic_shared_ptr<X> apx;
30 
31         boost::shared_ptr<X> p2 = apx.load();
32 
33         BOOST_TEST_EQ( p2.get(), (X*)0 );
34         BOOST_TEST_EQ( p2.use_count(), 0 );
35     }
36 
37     // shared_ptr constructor
38 
39     {
40         boost::shared_ptr<X> px( new X );
41         boost::atomic_shared_ptr<X> apx( px );
42 
43         boost::shared_ptr<X> p2 = apx.load();
44 
45         BOOST_TEST_EQ( px, p2 );
46         BOOST_TEST_EQ( px.use_count(), 3 );
47         BOOST_TEST_EQ( p2.use_count(), 3 );
48     }
49 
50     // shared_ptr assignment
51 
52     {
53         boost::shared_ptr<X> px0( new X );
54         boost::atomic_shared_ptr<X> apx( px0 );
55 
56         boost::shared_ptr<X> px( new X );
57         apx = px;
58 
59         boost::shared_ptr<X> p2 = apx.load();
60 
61         BOOST_TEST_EQ( px, p2 );
62         BOOST_TEST_EQ( px.use_count(), 3 );
63         BOOST_TEST_EQ( p2.use_count(), 3 );
64     }
65 
66     // load, w/ mo
67 
68     {
69         boost::shared_ptr<X> px( new X );
70         boost::atomic_shared_ptr<X> apx( px );
71 
72         boost::shared_ptr<X> p2 = apx.load( boost::memory_order_acquire );
73 
74         BOOST_TEST_EQ( px, p2 );
75         BOOST_TEST_EQ( px.use_count(), 3 );
76         BOOST_TEST_EQ( p2.use_count(), 3 );
77     }
78 
79     // operator shared_ptr
80 
81     {
82         boost::shared_ptr<X> px( new X );
83         boost::atomic_shared_ptr<X> apx( px );
84 
85         boost::shared_ptr<X> p2 = apx;
86 
87         BOOST_TEST_EQ( px, p2 );
88         BOOST_TEST_EQ( px.use_count(), 3 );
89         BOOST_TEST_EQ( p2.use_count(), 3 );
90     }
91 
92     // store
93 
94     {
95         boost::shared_ptr<X> px0( new X );
96         boost::atomic_shared_ptr<X> apx( px0 );
97 
98         boost::shared_ptr<X> px( new X );
99         apx.store( px );
100 
101         boost::shared_ptr<X> p2 = apx.load();
102 
103         BOOST_TEST_EQ( px, p2 );
104         BOOST_TEST_EQ( px.use_count(), 3 );
105         BOOST_TEST_EQ( p2.use_count(), 3 );
106     }
107 
108     // store, w/ mo
109 
110     {
111         boost::shared_ptr<X> px0( new X );
112         boost::atomic_shared_ptr<X> apx( px0 );
113 
114         boost::shared_ptr<X> px( new X );
115         apx.store( px, boost::memory_order_release );
116 
117         boost::shared_ptr<X> p2 = apx.load();
118 
119         BOOST_TEST_EQ( px, p2 );
120         BOOST_TEST_EQ( px.use_count(), 3 );
121         BOOST_TEST_EQ( p2.use_count(), 3 );
122     }
123 
124     // exchange
125 
126     {
127         boost::shared_ptr<X> px0( new X );
128         boost::atomic_shared_ptr<X> apx( px0 );
129 
130         boost::shared_ptr<X> px( new X );
131         boost::shared_ptr<X> p1 = apx.exchange( px );
132 
133         BOOST_TEST_EQ( px0, p1 );
134         BOOST_TEST_EQ( px0.use_count(), 2 );
135         BOOST_TEST_EQ( p1.use_count(), 2 );
136 
137         boost::shared_ptr<X> p2 = apx.load();
138 
139         BOOST_TEST_EQ( px, p2 );
140         BOOST_TEST_EQ( px.use_count(), 3 );
141         BOOST_TEST_EQ( p2.use_count(), 3 );
142     }
143 
144     // exchange, w/ mo
145 
146     {
147         boost::shared_ptr<X> px0( new X );
148         boost::atomic_shared_ptr<X> apx( px0 );
149 
150         boost::shared_ptr<X> px( new X );
151         boost::shared_ptr<X> p1 = apx.exchange( px, boost::memory_order_acq_rel );
152 
153         BOOST_TEST_EQ( px0, p1 );
154         BOOST_TEST_EQ( px0.use_count(), 2 );
155         BOOST_TEST_EQ( p1.use_count(), 2 );
156 
157         boost::shared_ptr<X> p2 = apx.load();
158 
159         BOOST_TEST_EQ( px, p2 );
160         BOOST_TEST_EQ( px.use_count(), 3 );
161         BOOST_TEST_EQ( p2.use_count(), 3 );
162     }
163 
164     // compare_exchange_weak
165 
166     {
167         boost::shared_ptr<X> px( new X );
168         boost::atomic_shared_ptr<X> apx( px );
169 
170         boost::shared_ptr<X> px2( new X );
171         boost::shared_ptr<X> cmp;
172 
173         bool r = apx.compare_exchange_weak( cmp, px2 );
174         BOOST_TEST( !r );
175         BOOST_TEST_SP_EQ( apx.load(), px );
176         BOOST_TEST_SP_EQ( cmp, px );
177 
178         r = apx.compare_exchange_weak( cmp, px2 );
179         BOOST_TEST( r );
180         BOOST_TEST_SP_EQ( apx.load(), px2 );
181     }
182 
183     // compare_exchange_weak, w/ mo
184 
185     {
186         boost::shared_ptr<X> px( new X );
187         boost::atomic_shared_ptr<X> apx( px );
188 
189         boost::shared_ptr<X> px2( new X );
190         boost::shared_ptr<X> cmp;
191 
192         bool r = apx.compare_exchange_weak( cmp, px2, boost::memory_order_seq_cst, boost::memory_order_seq_cst );
193         BOOST_TEST( !r );
194         BOOST_TEST_SP_EQ( apx.load(), px );
195         BOOST_TEST_SP_EQ( cmp, px );
196 
197         r = apx.compare_exchange_weak( cmp, px2, boost::memory_order_seq_cst, boost::memory_order_seq_cst );
198         BOOST_TEST( r );
199         BOOST_TEST_SP_EQ( apx.load(), px2 );
200     }
201 
202     // compare_exchange_weak, rv
203 
204     {
205         boost::shared_ptr<X> px( new X );
206         boost::atomic_shared_ptr<X> apx( px );
207 
208         boost::shared_ptr<X> cmp;
209 
210         bool r = apx.compare_exchange_weak( cmp, boost::shared_ptr<X>() );
211 
212         BOOST_TEST( !r );
213         BOOST_TEST_SP_EQ( apx.load(), px );
214         BOOST_TEST_SP_EQ( cmp, px );
215 
216         r = apx.compare_exchange_weak( cmp, boost::shared_ptr<X>() );
217 
218         BOOST_TEST( r );
219         BOOST_TEST( apx.load().get() == 0 );
220         BOOST_TEST( apx.load().use_count() == 0 );
221     }
222 
223     // compare_exchange_weak, rv, w/ mo
224 
225     {
226         boost::shared_ptr<X> px( new X );
227         boost::atomic_shared_ptr<X> apx( px );
228 
229         boost::shared_ptr<X> cmp;
230 
231         bool r = apx.compare_exchange_weak( cmp, boost::shared_ptr<X>(), boost::memory_order_seq_cst, boost::memory_order_seq_cst );
232 
233         BOOST_TEST( !r );
234         BOOST_TEST_SP_EQ( apx.load(), px );
235         BOOST_TEST_SP_EQ( cmp, px );
236 
237         r = apx.compare_exchange_weak( cmp, boost::shared_ptr<X>(), boost::memory_order_seq_cst, boost::memory_order_seq_cst );
238 
239         BOOST_TEST( r );
240         BOOST_TEST( apx.load().get() == 0 );
241         BOOST_TEST( apx.load().use_count() == 0 );
242     }
243 
244     // compare_exchange_strong
245 
246     {
247         boost::shared_ptr<X> px( new X );
248         boost::atomic_shared_ptr<X> apx( px );
249 
250         boost::shared_ptr<X> px2( new X );
251         boost::shared_ptr<X> cmp;
252 
253         bool r = apx.compare_exchange_strong( cmp, px2 );
254         BOOST_TEST( !r );
255         BOOST_TEST_SP_EQ( apx.load(), px );
256         BOOST_TEST_SP_EQ( cmp, px );
257 
258         r = apx.compare_exchange_strong( cmp, px2 );
259         BOOST_TEST( r );
260         BOOST_TEST_SP_EQ( apx.load(), px2 );
261     }
262 
263     // compare_exchange_strong, w/ mo
264 
265     {
266         boost::shared_ptr<X> px( new X );
267         boost::atomic_shared_ptr<X> apx( px );
268 
269         boost::shared_ptr<X> px2( new X );
270         boost::shared_ptr<X> cmp;
271 
272         bool r = apx.compare_exchange_strong( cmp, px2, boost::memory_order_seq_cst, boost::memory_order_seq_cst );
273         BOOST_TEST( !r );
274         BOOST_TEST_SP_EQ( apx.load(), px );
275         BOOST_TEST_SP_EQ( cmp, px );
276 
277         r = apx.compare_exchange_strong( cmp, px2, boost::memory_order_seq_cst, boost::memory_order_seq_cst );
278         BOOST_TEST( r );
279         BOOST_TEST_SP_EQ( apx.load(), px2 );
280     }
281 
282     // compare_exchange_strong, rv
283 
284     {
285         boost::shared_ptr<X> px( new X );
286         boost::atomic_shared_ptr<X> apx( px );
287 
288         boost::shared_ptr<X> cmp;
289 
290         bool r = apx.compare_exchange_strong( cmp, boost::shared_ptr<X>() );
291 
292         BOOST_TEST( !r );
293         BOOST_TEST_SP_EQ( apx.load(), px );
294         BOOST_TEST_SP_EQ( cmp, px );
295 
296         r = apx.compare_exchange_strong( cmp, boost::shared_ptr<X>() );
297 
298         BOOST_TEST( r );
299         BOOST_TEST( apx.load().get() == 0 );
300         BOOST_TEST( apx.load().use_count() == 0 );
301     }
302 
303     // compare_exchange_strong, rv, w/ mo
304 
305     {
306         boost::shared_ptr<X> px( new X );
307         boost::atomic_shared_ptr<X> apx( px );
308 
309         boost::shared_ptr<X> cmp;
310 
311         bool r = apx.compare_exchange_strong( cmp, boost::shared_ptr<X>(), boost::memory_order_seq_cst, boost::memory_order_seq_cst );
312 
313         BOOST_TEST( !r );
314         BOOST_TEST_SP_EQ( apx.load(), px );
315         BOOST_TEST_SP_EQ( cmp, px );
316 
317         r = apx.compare_exchange_strong( cmp, boost::shared_ptr<X>(), boost::memory_order_seq_cst, boost::memory_order_seq_cst );
318 
319         BOOST_TEST( r );
320         BOOST_TEST( apx.load().get() == 0 );
321         BOOST_TEST( apx.load().use_count() == 0 );
322     }
323 
324     return boost::report_errors();
325 }
326