cas64strong.hpp
Go to the documentation of this file.
1 #ifndef BOOST_DETAIL_ATOMIC_CAS64STRONG_HPP
2 #define BOOST_DETAIL_ATOMIC_CAS64STRONG_HPP
3 
4 // Distributed under the Boost Software License, Version 1.0.
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // Copyright (c) 2011 Helge Bahmann
9 
10 // Build 64-bit atomic operation from platform_cmpxchg64_strong
11 // primitive. It is assumed that 64-bit loads/stores are not
12 // atomic, so they are funnelled through cmpxchg as well.
13 
14 #include <boost/memory_order.hpp>
16 
17 namespace boost {
18 namespace detail {
19 namespace atomic {
20 
21 /* integral types */
22 
23 template<typename T, bool Sign>
24 class base_atomic<T, int, 8, Sign> {
26  typedef T value_type;
27  typedef T difference_type;
28 public:
29  explicit base_atomic(value_type v) : v_(v) {}
30  base_atomic(void) {}
31 
32  void
33  store(value_type v, memory_order order = memory_order_seq_cst) volatile
34  {
35  value_type expected = v_;
36  do {
37  } while (!compare_exchange_strong(expected, v, order, memory_order_relaxed));
38  }
39 
40  value_type
41  load(memory_order order = memory_order_seq_cst) const volatile
42  {
43  value_type v = const_cast<const volatile value_type &>(v_);
44  do {
45  } while (!const_cast<base_atomic *>(this)->compare_exchange_strong(v, v, order, memory_order_relaxed));
46  return v;
47  }
48 
49  value_type
50  exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
51  {
52  value_type original = load(memory_order_relaxed);
53  do {
54  } while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
55  return original;
56  }
57 
58  bool
60  value_type & expected,
61  value_type desired,
62  memory_order success_order,
63  memory_order failure_order) volatile
64  {
65  return compare_exchange_strong(expected, desired, success_order, failure_order);
66  }
67 
68  bool
70  value_type & expected,
71  value_type desired,
72  memory_order success_order,
73  memory_order failure_order) volatile
74  {
75  platform_fence_before(success_order);
76 
77  bool success = platform_cmpxchg64_strong(expected, desired, &v_);
78 
79  if (success) {
80  platform_fence_after(success_order);
81  } else {
82  platform_fence_after(failure_order);
83  }
84 
85  return success;
86  }
87 
88  value_type
89  fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile
90  {
91  value_type original = load(memory_order_relaxed);
92  do {
93  } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
94  return original;
95  }
96 
97  value_type
98  fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile
99  {
100  value_type original = load(memory_order_relaxed);
101  do {
102  } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
103  return original;
104  }
105 
106  value_type
107  fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile
108  {
109  value_type original = load(memory_order_relaxed);
110  do {
111  } while (!compare_exchange_weak(original, original & v, order, memory_order_relaxed));
112  return original;
113  }
114 
115  value_type
116  fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile
117  {
118  value_type original = load(memory_order_relaxed);
119  do {
120  } while (!compare_exchange_weak(original, original | v, order, memory_order_relaxed));
121  return original;
122  }
123 
124  value_type
125  fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile
126  {
127  value_type original = load(memory_order_relaxed);
128  do {
129  } while (!compare_exchange_weak(original, original ^ v, order, memory_order_relaxed));
130  return original;
131  }
132 
133  bool
134  is_lock_free(void) const volatile
135  {
136  return true;
137  }
138 
140 private:
141  base_atomic(const base_atomic &) /* = delete */ ;
142  void operator=(const base_atomic &) /* = delete */ ;
143  value_type v_;
144 };
145 
146 /* pointer types */
147 
148 template<bool Sign>
149 class base_atomic<void *, void *, 8, Sign> {
151  typedef void * value_type;
152  typedef ptrdiff_t difference_type;
153 public:
154  explicit base_atomic(value_type v) : v_(v) {}
155  base_atomic(void) {}
156 
157  void
158  store(value_type v, memory_order order = memory_order_seq_cst) volatile
159  {
160  value_type expected = v_;
161  do {
162  } while (!compare_exchange_strong(expected, v, order, memory_order_relaxed));
163  }
164 
165  value_type
166  load(memory_order order = memory_order_seq_cst) const volatile
167  {
168  value_type v = const_cast<const volatile value_type &>(v_);
169  do {
170  } while (!const_cast<base_atomic *>(this)->compare_exchange_strong(v, v, order, memory_order_relaxed));
171  return v;
172  }
173 
174  value_type
175  exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
176  {
177  value_type original = load(memory_order_relaxed);
178  do {
179  } while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
180  return original;
181  }
182 
183  bool
185  value_type & expected,
186  value_type desired,
187  memory_order success_order,
188  memory_order failure_order) volatile
189  {
190  return compare_exchange_strong(expected, desired, success_order, failure_order);
191  }
192 
193  bool
195  value_type & expected,
196  value_type desired,
197  memory_order success_order,
198  memory_order failure_order) volatile
199  {
200  platform_fence_before(success_order);
201 
202  bool success = platform_cmpxchg64_strong(expected, desired, &v_);
203 
204  if (success) {
205  platform_fence_after(success_order);
206  } else {
207  platform_fence_after(failure_order);
208  }
209 
210  return success;
211  }
212 
213  value_type
214  fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile
215  {
216  value_type original = load(memory_order_relaxed);
217  do {
218  } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
219  return original;
220  }
221 
222  value_type
223  fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile
224  {
225  value_type original = load(memory_order_relaxed);
226  do {
227  } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
228  return original;
229  }
230 
231  bool
232  is_lock_free(void) const volatile
233  {
234  return true;
235  }
236 
238 private:
239  base_atomic(const base_atomic &) /* = delete */ ;
240  void operator=(const base_atomic &) /* = delete */ ;
241  value_type v_;
242 };
243 
244 template<typename T, bool Sign>
245 class base_atomic<T *, void *, 8, Sign> {
247  typedef T * value_type;
248  typedef ptrdiff_t difference_type;
249 public:
250  explicit base_atomic(value_type v) : v_(v) {}
251  base_atomic(void) {}
252 
253  void
254  store(value_type v, memory_order order = memory_order_seq_cst) volatile
255  {
256  value_type expected = v_;
257  do {
258  } while (!compare_exchange_strong(expected, v, order, memory_order_relaxed));
259  }
260 
261  value_type
262  load(memory_order order = memory_order_seq_cst) const volatile
263  {
264  value_type v = const_cast<const volatile value_type &>(v_);
265  do {
266  } while (!const_cast<base_atomic *>(this)->compare_exchange_strong(v, v, order, memory_order_relaxed));
267  return v;
268  }
269 
270  value_type
271  exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
272  {
273  value_type original = load(memory_order_relaxed);
274  do {
275  } while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
276  return original;
277  }
278 
279  bool
281  value_type & expected,
282  value_type desired,
283  memory_order success_order,
284  memory_order failure_order) volatile
285  {
286  return compare_exchange_strong(expected, desired, success_order, failure_order);
287  }
288 
289  bool
291  value_type & expected,
292  value_type desired,
293  memory_order success_order,
294  memory_order failure_order) volatile
295  {
296  platform_fence_before(success_order);
297 
298  bool success = platform_cmpxchg64_strong(expected, desired, &v_);
299 
300  if (success) {
301  platform_fence_after(success_order);
302  } else {
303  platform_fence_after(failure_order);
304  }
305 
306  return success;
307  }
308 
309  value_type
310  fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile
311  {
312  value_type original = load(memory_order_relaxed);
313  do {
314  } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
315  return original;
316  }
317 
318  value_type
319  fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile
320  {
321  value_type original = load(memory_order_relaxed);
322  do {
323  } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
324  return original;
325  }
326 
327  bool
328  is_lock_free(void) const volatile
329  {
330  return true;
331  }
332 
334 private:
335  base_atomic(const base_atomic &) /* = delete */ ;
336  void operator=(const base_atomic &) /* = delete */ ;
337  value_type v_;
338 };
339 
340 /* generic types */
341 
342 template<typename T, bool Sign>
343 class base_atomic<T, void, 8, Sign> {
345  typedef T value_type;
346  typedef uint64_t storage_type;
347 public:
348  explicit base_atomic(value_type v) : v_(0)
349  {
350  memcpy(&v_, &v, sizeof(value_type));
351  }
352  base_atomic(void) : v_(0) {}
353 
354  void
355  store(value_type v, memory_order order = memory_order_seq_cst) volatile
356  {
357  value_type expected;
358  memcpy(&expected, const_cast<storage_type *>(&v_), sizeof(value_type));
359  do {
360  } while (!compare_exchange_strong(expected, v, order, memory_order_relaxed));
361  }
362 
363  value_type
364  load(memory_order order = memory_order_seq_cst) const volatile
365  {
366  value_type v;
367  memcpy(&v, const_cast<storage_type *>(&v_), sizeof(value_type));
368  do {
369  } while (!const_cast<base_atomic *>(this)->compare_exchange_strong(v, v, order, memory_order_relaxed));
370  return v;
371  }
372 
373  value_type
374  exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
375  {
376  value_type original = load(memory_order_relaxed);
377  do {
378  } while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
379  return original;
380  }
381 
382  bool
384  value_type & expected,
385  value_type desired,
386  memory_order success_order,
387  memory_order failure_order) volatile
388  {
389  return compare_exchange_strong(expected, desired, success_order, failure_order);
390  }
391 
392  bool
394  value_type & expected,
395  value_type desired,
396  memory_order success_order,
397  memory_order failure_order) volatile
398  {
399 
400  storage_type expected_s = 0, desired_s = 0;
401  memcpy(&expected_s, &expected, sizeof(value_type));
402  memcpy(&desired_s, &desired, sizeof(value_type));
403 
404  platform_fence_before(success_order);
405  bool success = platform_cmpxchg64_strong(expected_s, desired_s, &v_);
406 
407  if (success) {
408  platform_fence_after(success_order);
409  } else {
410  platform_fence_after(failure_order);
411  memcpy(&expected, &expected_s, sizeof(value_type));
412  }
413 
414  return success;
415  }
416 
417  bool
418  is_lock_free(void) const volatile
419  {
420  return true;
421  }
422 
424 private:
425  base_atomic(const base_atomic &) /* = delete */ ;
426  void operator=(const base_atomic &) /* = delete */ ;
427  storage_type v_;
428 };
429 
430 }
431 }
432 }
433 
434 #endif
value_type exchange(value_type v, memory_order order=memory_order_seq_cst) volatile
Definition: cas64strong.hpp:50
bool compare_exchange_strong(value_type &expected, value_type desired, memory_order, memory_order) volatile
Definition: base.hpp:166
value_type fetch_sub(difference_type v, memory_order order=memory_order_seq_cst) volatile
Definition: base.hpp:116
bool compare_exchange_strong(value_type &expected, value_type desired, memory_order success_order, memory_order failure_order) volatile
void store(value_type v, memory_order order=memory_order_seq_cst) volatile
bool compare_exchange_weak(value_type &expected, value_type desired, memory_order success_order, memory_order failure_order) volatile
bool compare_exchange_weak(value_type &expected, value_type desired, memory_order success_order, memory_order failure_order) volatile
Definition: cas64strong.hpp:59
value_type fetch_add(value_type v, memory_order order=memory_order_seq_cst) volatile
Definition: cas64strong.hpp:89
value_type fetch_and(value_type v, memory_order order=memory_order_seq_cst) volatile
void store(value_type v, memory_order order=memory_order_seq_cst) volatile
Definition: cas64strong.hpp:33
value_type fetch_add(difference_type v, memory_order order=memory_order_seq_cst) volatile
value_type fetch_sub(difference_type v, memory_order order=memory_order_seq_cst) volatile
value_type fetch_sub(value_type v, memory_order order=memory_order_seq_cst) volatile
Definition: cas64strong.hpp:98
value_type exchange(value_type v, memory_order order=memory_order_seq_cst) volatile
#define BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
Definition: base.hpp:107
bool compare_exchange_strong(value_type &expected, value_type desired, memory_order success_order, memory_order failure_order) volatile
Definition: cas64strong.hpp:69
value_type fetch_xor(value_type v, memory_order order=memory_order_seq_cst) volatile
value_type exchange(value_type v, memory_order order=memory_order_seq_cst) volatile
value_type load(memory_order=memory_order_seq_cst) volatileconst
Definition: base.hpp:156
bool compare_exchange_weak(value_type &expected, value_type desired, memory_order success_order, memory_order failure_order) volatile
bool compare_exchange_strong(value_type &expected, value_type desired, memory_order success_order, memory_order failure_order) volatile
static void platform_fence_after(memory_order order)
Definition: gcc-armv6+.hpp:116
void store(value_type v, memory_order order=memory_order_seq_cst) volatile
#define BOOST_ATOMIC_DECLARE_BASE_OPERATORS
Definition: base.hpp:19
value_type load(memory_order order=memory_order_seq_cst) const volatile
Definition: cas64strong.hpp:41
value_type fetch_add(difference_type v, memory_order order=memory_order_seq_cst) volatile
void store(value_type v, memory_order order=memory_order_seq_cst) volatile
value_type load(memory_order order=memory_order_seq_cst) const volatile
value_type exchange(value_type v, memory_order order=memory_order_seq_cst) volatile
bool compare_exchange_weak(value_type &expected, value_type desired, memory_order success_order, memory_order failure_order) volatile
bool compare_exchange_weak(value_type &expected, value_type desired, memory_order success_order, memory_order failure_order) volatile
Definition: base.hpp:184
value_type fetch_or(value_type v, memory_order order=memory_order_seq_cst) volatile
value_type load(memory_order order=memory_order_seq_cst) const volatile
value_type load(memory_order order=memory_order_seq_cst) const volatile
#define BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
Definition: base.hpp:111
static void platform_fence_before(memory_order order)
Definition: gcc-armv6+.hpp:103
void operator=(const base_atomic &)
bool compare_exchange_strong(value_type &expected, value_type desired, memory_order success_order, memory_order failure_order) volatile


rosatomic
Author(s): Josh Faust
autogenerated on Fri Apr 5 2019 02:16:35