base.hpp
Go to the documentation of this file.
1 #ifndef BOOST_DETAIL_ATOMIC_BASE_HPP
2 #define BOOST_DETAIL_ATOMIC_BASE_HPP
3 
4 // Copyright (c) 2009 Helge Bahmann
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 // See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9 
10 // Base class definition and fallback implementation.
11 // To be overridden (through partial specialization) by
12 // platform implementations.
13 
14 #include <string.h>
15 
16 #include <boost/memory_order.hpp>
17 #include <boost/smart_ptr/detail/spinlock_pool.hpp>
18 
19 #define BOOST_ATOMIC_DECLARE_BASE_OPERATORS \
20  operator value_type(void) volatile const \
21  { \
22  return load(memory_order_seq_cst); \
23  } \
24  \
25  this_type & \
26  operator=(value_type v) volatile \
27  { \
28  store(v, memory_order_seq_cst); \
29  return *const_cast<this_type *>(this); \
30  } \
31  \
32  bool \
33  compare_exchange_strong( \
34  value_type & expected, \
35  value_type desired, \
36  memory_order order = memory_order_seq_cst) volatile \
37  { \
38  return compare_exchange_strong(expected, desired, order, calculate_failure_order(order)); \
39  } \
40  \
41  bool \
42  compare_exchange_weak( \
43  value_type & expected, \
44  value_type desired, \
45  memory_order order = memory_order_seq_cst) volatile \
46  { \
47  return compare_exchange_weak(expected, desired, order, calculate_failure_order(order)); \
48  } \
49  \
50 
51 #define BOOST_ATOMIC_DECLARE_ADDITIVE_OPERATORS \
52  value_type \
53  operator++(int) volatile \
54  { \
55  return fetch_add(1); \
56  } \
57  \
58  value_type \
59  operator++(void) volatile \
60  { \
61  return fetch_add(1) + 1; \
62  } \
63  \
64  value_type \
65  operator--(int) volatile \
66  { \
67  return fetch_sub(1); \
68  } \
69  \
70  value_type \
71  operator--(void) volatile \
72  { \
73  return fetch_sub(1) - 1; \
74  } \
75  \
76  value_type \
77  operator+=(difference_type v) volatile \
78  { \
79  return fetch_add(v) + v; \
80  } \
81  \
82  value_type \
83  operator-=(difference_type v) volatile \
84  { \
85  return fetch_sub(v) - v; \
86  } \
87 
88 #define BOOST_ATOMIC_DECLARE_BIT_OPERATORS \
89  value_type \
90  operator&=(difference_type v) volatile \
91  { \
92  return fetch_and(v) & v; \
93  } \
94  \
95  value_type \
96  operator|=(difference_type v) volatile \
97  { \
98  return fetch_or(v) | v; \
99  } \
100  \
101  value_type \
102  operator^=(difference_type v) volatile \
103  { \
104  return fetch_xor(v) ^ v; \
105  } \
106 
107 #define BOOST_ATOMIC_DECLARE_POINTER_OPERATORS \
108  BOOST_ATOMIC_DECLARE_BASE_OPERATORS \
109  BOOST_ATOMIC_DECLARE_ADDITIVE_OPERATORS \
110 
111 #define BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS \
112  BOOST_ATOMIC_DECLARE_BASE_OPERATORS \
113  BOOST_ATOMIC_DECLARE_ADDITIVE_OPERATORS \
114  BOOST_ATOMIC_DECLARE_BIT_OPERATORS \
115 
116 namespace boost {
117 namespace detail {
118 namespace atomic {
119 
120 static inline memory_order
122 {
123  switch(order) {
125  return memory_order_acquire;
127  return memory_order_relaxed;
128  default:
129  return order;
130  }
131 }
132 
133 template<typename T, typename C , unsigned int Size, bool Sign>
134 class base_atomic {
135 private:
137  typedef T value_type;
138  typedef detail::spinlock_pool<0>::scoped_lock guard_type;
139 public:
140  base_atomic(void) {}
141 
142  explicit base_atomic(const value_type & v)
143  {
144  memcpy(&v_, &v, Size);
145  }
146 
147  void
148  store(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile
149  {
150  guard_type guard(const_cast<char *>(v_));
151 
152  memcpy(const_cast<char *>(v_), &v, Size);
153  }
154 
155  value_type
156  load(memory_order /*order*/ = memory_order_seq_cst) volatile const
157  {
158  guard_type guard(const_cast<const char *>(v_));
159 
160  value_type v;
161  memcpy(&v, const_cast<const char *>(v_), Size);
162  return v;
163  }
164 
165  bool
167  value_type & expected,
168  value_type desired,
169  memory_order /*success_order*/,
170  memory_order /*failure_order*/) volatile
171  {
172  guard_type guard(const_cast<char *>(v_));
173 
174  if (memcmp(const_cast<char *>(v_), &expected, Size) == 0) {
175  memcpy(const_cast<char *>(v_), &desired, Size);
176  return true;
177  } else {
178  memcpy(&expected, const_cast<char *>(v_), Size);
179  return false;
180  }
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  value_type
194  exchange(value_type v, memory_order /*order*/=memory_order_seq_cst) volatile
195  {
196  guard_type guard(const_cast<char *>(v_));
197 
198  value_type tmp;
199  memcpy(&tmp, const_cast<char *>(v_), Size);
200 
201  memcpy(const_cast<char *>(v_), &v, Size);
202  return tmp;
203  }
204 
205  bool
206  is_lock_free(void) const volatile
207  {
208  return false;
209  }
210 
212 private:
213  base_atomic(const base_atomic &) /* = delete */ ;
214  void operator=(const base_atomic &) /* = delete */ ;
215 
216  char v_[Size];
217 };
218 
219 template<typename T, unsigned int Size, bool Sign>
220 class base_atomic<T, int, Size, Sign> {
221 private:
223  typedef T value_type;
224  typedef T difference_type;
225  typedef detail::spinlock_pool<0>::scoped_lock guard_type;
226 public:
227  explicit base_atomic(value_type v) : v_(v) {}
228  base_atomic(void) {}
229 
230  void
231  store(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile
232  {
233  guard_type guard(const_cast<value_type *>(&v_));
234 
235  v_ = v;
236  }
237 
238  value_type
239  load(memory_order /*order*/ = memory_order_seq_cst) const volatile
240  {
241  guard_type guard(const_cast<value_type *>(&v_));
242 
243  value_type v = const_cast<const volatile value_type &>(v_);
244  return v;
245  }
246 
247  value_type
248  exchange(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile
249  {
250  guard_type guard(const_cast<value_type *>(&v_));
251 
252  value_type old = v_;
253  v_ = v;
254  return old;
255  }
256 
257  bool
258  compare_exchange_strong(value_type & expected, value_type desired,
259  memory_order /*success_order*/,
260  memory_order /*failure_order*/) volatile
261  {
262  guard_type guard(const_cast<value_type *>(&v_));
263 
264  if (v_ == expected) {
265  v_ = desired;
266  return true;
267  } else {
268  expected = v_;
269  return false;
270  }
271  }
272 
273  bool
274  compare_exchange_weak(value_type & expected, value_type desired,
275  memory_order success_order,
276  memory_order failure_order) volatile
277  {
278  return compare_exchange_strong(expected, desired, success_order, failure_order);
279  }
280 
281  value_type
282  fetch_add(difference_type v, memory_order /*order*/ = memory_order_seq_cst) volatile
283  {
284  guard_type guard(const_cast<value_type *>(&v_));
285 
286  value_type old = v_;
287  v_ += v;
288  return old;
289  }
290 
291  value_type
292  fetch_sub(difference_type v, memory_order /*order*/ = memory_order_seq_cst) volatile
293  {
294  guard_type guard(const_cast<value_type *>(&v_));
295 
296  value_type old = v_;
297  v_ -= v;
298  return old;
299  }
300 
301  value_type
302  fetch_and(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile
303  {
304  guard_type guard(const_cast<value_type *>(&v_));
305 
306  value_type old = v_;
307  v_ &= v;
308  return old;
309  }
310 
311  value_type
312  fetch_or(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile
313  {
314  guard_type guard(const_cast<value_type *>(&v_));
315 
316  value_type old = v_;
317  v_ |= v;
318  return old;
319  }
320 
321  value_type
322  fetch_xor(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile
323  {
324  guard_type guard(const_cast<value_type *>(&v_));
325 
326  value_type old = v_;
327  v_ ^= v;
328  return old;
329  }
330 
331  bool
332  is_lock_free(void) const volatile
333  {
334  return false;
335  }
336 
338 private:
339  base_atomic(const base_atomic &) /* = delete */ ;
340  void operator=(const base_atomic &) /* = delete */ ;
341  value_type v_;
342 };
343 
344 template<typename T, unsigned int Size, bool Sign>
345 class base_atomic<T *, void *, Size, Sign> {
346 private:
348  typedef T * value_type;
349  typedef ptrdiff_t difference_type;
350  typedef detail::spinlock_pool<0>::scoped_lock guard_type;
351 public:
352  explicit base_atomic(value_type v) : v_(v) {}
353  base_atomic(void) {}
354 
355  void
356  store(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile
357  {
358  guard_type guard(const_cast<value_type *>(&v_));
359  v_ = v;
360  }
361 
362  value_type
363  load(memory_order /*order*/ = memory_order_seq_cst) const volatile
364  {
365  guard_type guard(const_cast<value_type *>(&v_));
366 
367  value_type v = const_cast<const volatile value_type &>(v_);
368  return v;
369  }
370 
371  value_type
372  exchange(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile
373  {
374  guard_type guard(const_cast<value_type *>(&v_));
375 
376  value_type old = v_;
377  v_ = v;
378  return old;
379  }
380 
381  bool
382  compare_exchange_strong(value_type & expected, value_type desired,
383  memory_order /*success_order*/,
384  memory_order /*failure_order*/) volatile
385  {
386  guard_type guard(const_cast<value_type *>(&v_));
387 
388  if (v_ == expected) {
389  v_ = desired;
390  return true;
391  } else {
392  expected = v_;
393  return false;
394  }
395  }
396 
397  bool
398  compare_exchange_weak(value_type & expected, value_type desired,
399  memory_order success_order,
400  memory_order failure_order) volatile
401  {
402  return compare_exchange_strong(expected, desired, success_order, failure_order);
403  }
404 
405  value_type fetch_add(difference_type v, memory_order /*order*/ = memory_order_seq_cst) volatile
406  {
407  guard_type guard(const_cast<value_type *>(&v_));
408 
409  value_type old = v_;
410  v_ += v;
411  return old;
412  }
413 
414  value_type fetch_sub(difference_type v, memory_order /*order*/ = memory_order_seq_cst) volatile
415  {
416  guard_type guard(const_cast<value_type *>(&v_));
417 
418  value_type old = v_;
419  v_ -= v;
420  return old;
421  }
422 
423  bool
424  is_lock_free(void) const volatile
425  {
426  return false;
427  }
428 
430 private:
431  base_atomic(const base_atomic &) /* = delete */ ;
432  void operator=(const base_atomic &) /* = delete */ ;
433  value_type v_;
434 };
435 
436 template<unsigned int Size, bool Sign>
437 class base_atomic<void *, void *, Size, Sign> {
438 private:
440  typedef void * value_type;
441  typedef detail::spinlock_pool<0>::scoped_lock guard_type;
442 public:
443  explicit base_atomic(value_type v) : v_(v) {}
444  base_atomic(void) {}
445 
446  void
447  store(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile
448  {
449  guard_type guard(const_cast<value_type *>(&v_));
450  v_ = v;
451  }
452 
453  value_type
454  load(memory_order /*order*/ = memory_order_seq_cst) const volatile
455  {
456  guard_type guard(const_cast<value_type *>(&v_));
457 
458  value_type v = const_cast<const volatile value_type &>(v_);
459  return v;
460  }
461 
462  value_type
463  exchange(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile
464  {
465  guard_type guard(const_cast<value_type *>(&v_));
466 
467  value_type old = v_;
468  v_ = v;
469  return old;
470  }
471 
472  bool
473  compare_exchange_strong(value_type & expected, value_type desired,
474  memory_order /*success_order*/,
475  memory_order /*failure_order*/) volatile
476  {
477  guard_type guard(const_cast<value_type *>(&v_));
478 
479  if (v_ == expected) {
480  v_ = desired;
481  return true;
482  } else {
483  expected = v_;
484  return false;
485  }
486  }
487 
488  bool
489  compare_exchange_weak(value_type & expected, value_type desired,
490  memory_order success_order,
491  memory_order failure_order) volatile
492  {
493  return compare_exchange_strong(expected, desired, success_order, failure_order);
494  }
495 
496  bool
497  is_lock_free(void) const volatile
498  {
499  return false;
500  }
501 
503 private:
504  base_atomic(const base_atomic &) /* = delete */ ;
505  void operator=(const base_atomic &) /* = delete */ ;
506  value_type v_;
507 };
508 
509 }
510 }
511 }
512 
513 #endif
value_type exchange(value_type v, memory_order=memory_order_seq_cst) volatile
Definition: base.hpp:372
bool compare_exchange_strong(value_type &expected, value_type desired, memory_order, memory_order) volatile
Definition: base.hpp:166
value_type fetch_add(difference_type v, memory_order=memory_order_seq_cst) volatile
Definition: base.hpp:282
bool compare_exchange_weak(value_type &expected, value_type desired, memory_order success_order, memory_order failure_order) volatile
Definition: base.hpp:489
Definition: base.hpp:116
detail::spinlock_pool< 0 >::scoped_lock guard_type
Definition: base.hpp:225
value_type load(memory_order=memory_order_seq_cst) const volatile
Definition: base.hpp:454
void store(value_type v, memory_order=memory_order_seq_cst) volatile
Definition: base.hpp:356
#define BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
Definition: base.hpp:107
value_type fetch_add(difference_type v, memory_order=memory_order_seq_cst) volatile
Definition: base.hpp:405
bool compare_exchange_weak(value_type &expected, value_type desired, memory_order success_order, memory_order failure_order) volatile
Definition: base.hpp:274
bool compare_exchange_strong(value_type &expected, value_type desired, memory_order, memory_order) volatile
Definition: base.hpp:382
value_type fetch_xor(value_type v, memory_order=memory_order_seq_cst) volatile
Definition: base.hpp:322
value_type load(memory_order=memory_order_seq_cst) volatileconst
Definition: base.hpp:156
bool compare_exchange_strong(value_type &expected, value_type desired, memory_order, memory_order) volatile
Definition: base.hpp:258
void store(value_type v, memory_order=memory_order_seq_cst) volatile
Definition: base.hpp:231
detail::spinlock_pool< 0 >::scoped_lock guard_type
Definition: base.hpp:441
static memory_order calculate_failure_order(memory_order order)
Definition: base.hpp:121
bool compare_exchange_weak(value_type &expected, value_type desired, memory_order success_order, memory_order failure_order) volatile
Definition: base.hpp:398
#define BOOST_ATOMIC_DECLARE_BASE_OPERATORS
Definition: base.hpp:19
base_atomic(const value_type &v)
Definition: base.hpp:142
value_type exchange(value_type v, memory_order=memory_order_seq_cst) volatile
Definition: base.hpp:463
value_type load(memory_order=memory_order_seq_cst) const volatile
Definition: base.hpp:239
void store(value_type v, memory_order=memory_order_seq_cst) volatile
Definition: base.hpp:148
value_type fetch_sub(difference_type v, memory_order=memory_order_seq_cst) volatile
Definition: base.hpp:292
bool compare_exchange_strong(value_type &expected, value_type desired, memory_order, memory_order) volatile
Definition: base.hpp:473
bool compare_exchange_weak(value_type &expected, value_type desired, memory_order success_order, memory_order failure_order) volatile
Definition: base.hpp:184
detail::spinlock_pool< 0 >::scoped_lock guard_type
Definition: base.hpp:350
value_type fetch_sub(difference_type v, memory_order=memory_order_seq_cst) volatile
Definition: base.hpp:414
value_type exchange(value_type v, memory_order=memory_order_seq_cst) volatile
Definition: base.hpp:194
#define BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
Definition: base.hpp:111
bool is_lock_free(void) const volatile
Definition: base.hpp:206
value_type load(memory_order=memory_order_seq_cst) const volatile
Definition: base.hpp:363
value_type fetch_and(value_type v, memory_order=memory_order_seq_cst) volatile
Definition: base.hpp:302
void operator=(const base_atomic &)
value_type fetch_or(value_type v, memory_order=memory_order_seq_cst) volatile
Definition: base.hpp:312
void store(value_type v, memory_order=memory_order_seq_cst) volatile
Definition: base.hpp:447
detail::spinlock_pool< 0 >::scoped_lock guard_type
Definition: base.hpp:138
value_type exchange(value_type v, memory_order=memory_order_seq_cst) volatile
Definition: base.hpp:248


rosatomic
Author(s): Josh Faust
autogenerated on Mon Jun 10 2019 14:44:41