1
#ifndef BOOST_ATOMIC_DETAIL_CAS64STRONG_HPP
2
#define BOOST_ATOMIC_DETAIL_CAS64STRONG_HPP
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)
8
// Copyright (c) 2011 Helge Bahmann
9
// Copyright (c) 2013 Tim Blechmann
11
// Build 64-bit atomic operation from platform_cmpxchg64_strong
12
// primitive. It is assumed that 64-bit loads/stores are not
13
// atomic, so they are funnelled through cmpxchg as well.
16
#include <boost/cstdint.hpp>
17
#include <boost/memory_order.hpp>
18
#include <boost/atomic/detail/config.hpp>
19
#include <boost/atomic/detail/base.hpp>
21
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE
31
template<typename T, bool Sign>
32
class base_atomic<T, int, 8, Sign>
34
typedef base_atomic this_type;
36
typedef T difference_type;
38
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
42
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
44
platform_fence_before_store(order);
45
platform_store64(v, &v_);
46
platform_fence_after_store(order);
50
load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
52
value_type v = platform_load64(&v_);
53
platform_fence_after_load(order);
58
exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
60
value_type original = load(memory_order_relaxed);
62
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
67
compare_exchange_weak(
68
value_type & expected,
70
memory_order success_order,
71
memory_order failure_order) volatile BOOST_NOEXCEPT
73
return compare_exchange_strong(expected, desired, success_order, failure_order);
77
compare_exchange_strong(
78
value_type & expected,
80
memory_order success_order,
81
memory_order failure_order) volatile BOOST_NOEXCEPT
83
platform_fence_before(success_order);
85
bool success = platform_cmpxchg64_strong(expected, desired, &v_);
88
platform_fence_after(success_order);
90
platform_fence_after(failure_order);
97
fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
99
value_type original = load(memory_order_relaxed);
101
} while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
106
fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
108
value_type original = load(memory_order_relaxed);
110
} while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
115
fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
117
value_type original = load(memory_order_relaxed);
119
} while (!compare_exchange_weak(original, original & v, order, memory_order_relaxed));
124
fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
126
value_type original = load(memory_order_relaxed);
128
} while (!compare_exchange_weak(original, original | v, order, memory_order_relaxed));
133
fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
135
value_type original = load(memory_order_relaxed);
137
} while (!compare_exchange_weak(original, original ^ v, order, memory_order_relaxed));
142
is_lock_free(void) const volatile BOOST_NOEXCEPT
147
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
149
base_atomic(const base_atomic &) /* = delete */ ;
150
void operator=(const base_atomic &) /* = delete */ ;
157
class base_atomic<void *, void *, 8, Sign>
159
typedef base_atomic this_type;
160
typedef void * value_type;
161
typedef ptrdiff_t difference_type;
163
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
167
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
169
platform_fence_before_store(order);
170
platform_store64(v, &v_);
171
platform_fence_after_store(order);
175
load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
177
value_type v = platform_load64(&v_);
178
platform_fence_after_load(order);
183
exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
185
value_type original = load(memory_order_relaxed);
187
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
192
compare_exchange_weak(
193
value_type & expected,
195
memory_order success_order,
196
memory_order failure_order) volatile BOOST_NOEXCEPT
198
return compare_exchange_strong(expected, desired, success_order, failure_order);
202
compare_exchange_strong(
203
value_type & expected,
205
memory_order success_order,
206
memory_order failure_order) volatile BOOST_NOEXCEPT
208
platform_fence_before(success_order);
210
bool success = platform_cmpxchg64_strong(expected, desired, &v_);
213
platform_fence_after(success_order);
215
platform_fence_after(failure_order);
222
fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
224
value_type original = load(memory_order_relaxed);
226
} while (!compare_exchange_weak(original, (char*)original + v, order, memory_order_relaxed));
231
fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
233
value_type original = load(memory_order_relaxed);
235
} while (!compare_exchange_weak(original, (char*)original - v, order, memory_order_relaxed));
240
is_lock_free(void) const volatile BOOST_NOEXCEPT
245
BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS
247
base_atomic(const base_atomic &) /* = delete */ ;
248
void operator=(const base_atomic &) /* = delete */ ;
252
template<typename T, bool Sign>
253
class base_atomic<T *, void *, 8, Sign>
255
typedef base_atomic this_type;
256
typedef T * value_type;
257
typedef ptrdiff_t difference_type;
259
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
263
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
265
platform_fence_before_store(order);
266
platform_store64(v, &v_);
267
platform_fence_after_store(order);
271
load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
273
value_type v = platform_load64(&v_);
274
platform_fence_after_load(order);
279
exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
281
value_type original = load(memory_order_relaxed);
283
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
288
compare_exchange_weak(
289
value_type & expected,
291
memory_order success_order,
292
memory_order failure_order) volatile BOOST_NOEXCEPT
294
return compare_exchange_strong(expected, desired, success_order, failure_order);
298
compare_exchange_strong(
299
value_type & expected,
301
memory_order success_order,
302
memory_order failure_order) volatile BOOST_NOEXCEPT
304
platform_fence_before(success_order);
306
bool success = platform_cmpxchg64_strong(expected, desired, &v_);
309
platform_fence_after(success_order);
311
platform_fence_after(failure_order);
318
fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
320
value_type original = load(memory_order_relaxed);
322
} while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
327
fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
329
value_type original = load(memory_order_relaxed);
331
} while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
336
is_lock_free(void) const volatile BOOST_NOEXCEPT
341
BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
343
base_atomic(const base_atomic &) /* = delete */ ;
344
void operator=(const base_atomic &) /* = delete */ ;
350
template<typename T, bool Sign>
351
class base_atomic<T, void, 8, Sign>
353
typedef base_atomic this_type;
354
typedef T value_type;
355
typedef uint64_t storage_type;
357
explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
359
memcpy(&v_, &v, sizeof(value_type));
364
store(value_type const& value, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
366
storage_type value_s = 0;
367
memcpy(&value_s, &value, sizeof(value_type));
368
platform_fence_before_store(order);
369
platform_store64(value_s, &v_);
370
platform_fence_after_store(order);
374
load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
376
storage_type value_s = platform_load64(&v_);
377
platform_fence_after_load(order);
379
memcpy(&value, &value_s, sizeof(value_type));
384
exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
386
value_type original = load(memory_order_relaxed);
388
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
393
compare_exchange_weak(
394
value_type & expected,
395
value_type const& desired,
396
memory_order success_order,
397
memory_order failure_order) volatile BOOST_NOEXCEPT
399
return compare_exchange_strong(expected, desired, success_order, failure_order);
403
compare_exchange_strong(
404
value_type & expected,
405
value_type const& desired,
406
memory_order success_order,
407
memory_order failure_order) volatile BOOST_NOEXCEPT
409
storage_type expected_s = 0, desired_s = 0;
410
memcpy(&expected_s, &expected, sizeof(value_type));
411
memcpy(&desired_s, &desired, sizeof(value_type));
413
platform_fence_before(success_order);
414
bool success = platform_cmpxchg64_strong(expected_s, desired_s, &v_);
417
platform_fence_after(success_order);
419
platform_fence_after(failure_order);
420
memcpy(&expected, &expected_s, sizeof(value_type));
427
is_lock_free(void) const volatile BOOST_NOEXCEPT
432
BOOST_ATOMIC_DECLARE_BASE_OPERATORS
434
base_atomic(const base_atomic &) /* = delete */ ;
435
void operator=(const base_atomic &) /* = delete */ ;