886 lines
25 KiB
C++
886 lines
25 KiB
C++
#ifndef BOOST_ATOMIC_DETAIL_CAS32STRONG_HPP
|
|
#define BOOST_ATOMIC_DETAIL_CAS32STRONG_HPP
|
|
|
|
// Distributed under the Boost Software License, Version 1.0.
|
|
// See accompanying file LICENSE_1_0.txt or copy at
|
|
// http://www.boost.org/LICENSE_1_0.txt)
|
|
//
|
|
// Copyright (c) 2011 Helge Bahmann
|
|
// Copyright (c) 2013 Tim Blechmann
|
|
|
|
|
|
// Build 8-, 16- and 32-bit atomic operations from
|
|
// a platform_cmpxchg32_strong primitive.
|
|
|
|
#include <cstddef>
|
|
#include <boost/cstdint.hpp>
|
|
#include <boost/memory_order.hpp>
|
|
#include <boost/atomic/detail/config.hpp>
|
|
#include <boost/atomic/detail/base.hpp>
|
|
|
|
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE
|
|
#pragma once
|
|
#endif
|
|
|
|
namespace boost {
|
|
namespace atomics {
|
|
namespace detail {
|
|
|
|
/* integral types */
|
|
|
|
template<typename T, bool Sign>
|
|
class base_atomic<T, int, 1, Sign>
|
|
{
|
|
typedef base_atomic this_type;
|
|
typedef T value_type;
|
|
typedef T difference_type;
|
|
typedef uint32_t storage_type;
|
|
public:
|
|
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
|
|
base_atomic(void) {}
|
|
|
|
void
|
|
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
platform_fence_before_store(order);
|
|
const_cast<volatile storage_type &>(v_) = v;
|
|
platform_fence_after_store(order);
|
|
}
|
|
|
|
value_type
|
|
load(memory_order order = memory_order_seq_cst) const volatile
|
|
{
|
|
value_type v = const_cast<const volatile storage_type &>(v_);
|
|
platform_fence_after_load(order);
|
|
return v;
|
|
}
|
|
|
|
value_type
|
|
exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
bool
|
|
compare_exchange_weak(
|
|
value_type & expected,
|
|
value_type desired,
|
|
memory_order success_order,
|
|
memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
{
|
|
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
|
}
|
|
|
|
bool
|
|
compare_exchange_strong(
|
|
value_type & expected,
|
|
value_type desired,
|
|
memory_order success_order,
|
|
memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
{
|
|
platform_fence_before(success_order);
|
|
|
|
storage_type expected_s = (storage_type) expected;
|
|
storage_type desired_s = (storage_type) desired;
|
|
|
|
bool success = platform_cmpxchg32_strong(expected_s, desired_s, &v_);
|
|
|
|
if (success) {
|
|
platform_fence_after(success_order);
|
|
} else {
|
|
platform_fence_after(failure_order);
|
|
expected = (value_type) expected_s;
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
value_type
|
|
fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
value_type
|
|
fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
value_type
|
|
fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, original & v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
value_type
|
|
fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, original | v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
value_type
|
|
fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, original ^ v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
bool
|
|
is_lock_free(void) const volatile
|
|
{
|
|
return true;
|
|
}
|
|
|
|
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
|
|
private:
|
|
base_atomic(const base_atomic &) /* = delete */ ;
|
|
void operator=(const base_atomic &) /* = delete */ ;
|
|
storage_type v_;
|
|
};
|
|
|
|
template<typename T, bool Sign>
|
|
class base_atomic<T, int, 2, Sign>
|
|
{
|
|
typedef base_atomic this_type;
|
|
typedef T value_type;
|
|
typedef T difference_type;
|
|
typedef uint32_t storage_type;
|
|
public:
|
|
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
|
|
base_atomic(void) {}
|
|
|
|
void
|
|
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
platform_fence_before_store(order);
|
|
const_cast<volatile storage_type &>(v_) = v;
|
|
platform_fence_after_store(order);
|
|
}
|
|
|
|
value_type
|
|
load(memory_order order = memory_order_seq_cst) const volatile
|
|
{
|
|
value_type v = const_cast<const volatile storage_type &>(v_);
|
|
platform_fence_after_load(order);
|
|
return v;
|
|
}
|
|
|
|
value_type
|
|
exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
bool
|
|
compare_exchange_weak(
|
|
value_type & expected,
|
|
value_type desired,
|
|
memory_order success_order,
|
|
memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
{
|
|
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
|
}
|
|
|
|
bool
|
|
compare_exchange_strong(
|
|
value_type & expected,
|
|
value_type desired,
|
|
memory_order success_order,
|
|
memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
{
|
|
platform_fence_before(success_order);
|
|
|
|
storage_type expected_s = (storage_type) expected;
|
|
storage_type desired_s = (storage_type) desired;
|
|
|
|
bool success = platform_cmpxchg32_strong(expected_s, desired_s, &v_);
|
|
|
|
if (success) {
|
|
platform_fence_after(success_order);
|
|
} else {
|
|
platform_fence_after(failure_order);
|
|
expected = (value_type) expected_s;
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
value_type
|
|
fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
value_type
|
|
fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
value_type
|
|
fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, original & v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
value_type
|
|
fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, original | v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
value_type
|
|
fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, original ^ v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
bool
|
|
is_lock_free(void) const volatile
|
|
{
|
|
return true;
|
|
}
|
|
|
|
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
|
|
private:
|
|
base_atomic(const base_atomic &) /* = delete */ ;
|
|
void operator=(const base_atomic &) /* = delete */ ;
|
|
storage_type v_;
|
|
};
|
|
|
|
template<typename T, bool Sign>
|
|
class base_atomic<T, int, 4, Sign>
|
|
{
|
|
typedef base_atomic this_type;
|
|
typedef T value_type;
|
|
typedef T difference_type;
|
|
public:
|
|
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
|
|
base_atomic(void) {}
|
|
|
|
void
|
|
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
platform_fence_before_store(order);
|
|
const_cast<volatile value_type &>(v_) = v;
|
|
platform_fence_after_store(order);
|
|
}
|
|
|
|
value_type
|
|
load(memory_order order = memory_order_seq_cst) const volatile
|
|
{
|
|
value_type v = const_cast<const volatile value_type &>(v_);
|
|
platform_fence_after_load(order);
|
|
return v;
|
|
}
|
|
|
|
value_type
|
|
exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
bool
|
|
compare_exchange_weak(
|
|
value_type & expected,
|
|
value_type desired,
|
|
memory_order success_order,
|
|
memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
{
|
|
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
|
}
|
|
|
|
bool
|
|
compare_exchange_strong(
|
|
value_type & expected,
|
|
value_type desired,
|
|
memory_order success_order,
|
|
memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
{
|
|
platform_fence_before(success_order);
|
|
|
|
bool success = platform_cmpxchg32_strong(expected, desired, &v_);
|
|
|
|
if (success) {
|
|
platform_fence_after(success_order);
|
|
} else {
|
|
platform_fence_after(failure_order);
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
value_type
|
|
fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
value_type
|
|
fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
value_type
|
|
fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, original & v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
value_type
|
|
fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, original | v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
value_type
|
|
fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, original ^ v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
bool
|
|
is_lock_free(void) const volatile
|
|
{
|
|
return true;
|
|
}
|
|
|
|
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
|
|
private:
|
|
base_atomic(const base_atomic &) /* = delete */ ;
|
|
void operator=(const base_atomic &) /* = delete */ ;
|
|
value_type v_;
|
|
};
|
|
|
|
/* pointer types */
|
|
|
|
template<bool Sign>
|
|
class base_atomic<void *, void *, 4, Sign>
|
|
{
|
|
typedef base_atomic this_type;
|
|
typedef void * value_type;
|
|
typedef ptrdiff_t difference_type;
|
|
public:
|
|
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
|
|
base_atomic(void) {}
|
|
|
|
void
|
|
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
platform_fence_before_store(order);
|
|
const_cast<volatile value_type &>(v_) = v;
|
|
platform_fence_after_store(order);
|
|
}
|
|
|
|
value_type
|
|
load(memory_order order = memory_order_seq_cst) const volatile
|
|
{
|
|
value_type v = const_cast<const volatile value_type &>(v_);
|
|
platform_fence_after_load(order);
|
|
return v;
|
|
}
|
|
|
|
value_type
|
|
exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
bool
|
|
compare_exchange_weak(
|
|
value_type & expected,
|
|
value_type desired,
|
|
memory_order success_order,
|
|
memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
{
|
|
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
|
}
|
|
|
|
bool
|
|
compare_exchange_strong(
|
|
value_type & expected,
|
|
value_type desired,
|
|
memory_order success_order,
|
|
memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
{
|
|
platform_fence_before(success_order);
|
|
|
|
bool success = platform_cmpxchg32_strong(expected, desired, &v_);
|
|
|
|
if (success) {
|
|
platform_fence_after(success_order);
|
|
} else {
|
|
platform_fence_after(failure_order);
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
value_type
|
|
fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, (char*)original + v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
value_type
|
|
fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, (char*)original - v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
bool
|
|
is_lock_free(void) const volatile
|
|
{
|
|
return true;
|
|
}
|
|
|
|
BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS
|
|
private:
|
|
base_atomic(const base_atomic &) /* = delete */ ;
|
|
void operator=(const base_atomic &) /* = delete */ ;
|
|
value_type v_;
|
|
};
|
|
|
|
template<typename T, bool Sign>
|
|
class base_atomic<T *, void *, 4, Sign>
|
|
{
|
|
typedef base_atomic this_type;
|
|
typedef T * value_type;
|
|
typedef ptrdiff_t difference_type;
|
|
public:
|
|
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
|
|
base_atomic(void) {}
|
|
|
|
void
|
|
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
platform_fence_before_store(order);
|
|
const_cast<volatile value_type &>(v_) = v;
|
|
platform_fence_after_store(order);
|
|
}
|
|
|
|
value_type
|
|
load(memory_order order = memory_order_seq_cst) const volatile
|
|
{
|
|
value_type v = const_cast<const volatile value_type &>(v_);
|
|
platform_fence_after_load(order);
|
|
return v;
|
|
}
|
|
|
|
value_type
|
|
exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
bool
|
|
compare_exchange_weak(
|
|
value_type & expected,
|
|
value_type desired,
|
|
memory_order success_order,
|
|
memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
{
|
|
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
|
}
|
|
|
|
bool
|
|
compare_exchange_strong(
|
|
value_type & expected,
|
|
value_type desired,
|
|
memory_order success_order,
|
|
memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
{
|
|
platform_fence_before(success_order);
|
|
|
|
bool success = platform_cmpxchg32_strong(expected, desired, &v_);
|
|
|
|
if (success) {
|
|
platform_fence_after(success_order);
|
|
} else {
|
|
platform_fence_after(failure_order);
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
value_type
|
|
fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
value_type
|
|
fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
bool
|
|
is_lock_free(void) const volatile
|
|
{
|
|
return true;
|
|
}
|
|
|
|
BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
|
|
private:
|
|
base_atomic(const base_atomic &) /* = delete */ ;
|
|
void operator=(const base_atomic &) /* = delete */ ;
|
|
value_type v_;
|
|
};
|
|
|
|
/* generic types */
|
|
|
|
template<typename T, bool Sign>
|
|
class base_atomic<T, void, 1, Sign>
|
|
{
|
|
typedef base_atomic this_type;
|
|
typedef T value_type;
|
|
typedef uint32_t storage_type;
|
|
public:
|
|
explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
|
|
{
|
|
memcpy(&v_, &v, sizeof(value_type));
|
|
}
|
|
|
|
base_atomic(void) {}
|
|
|
|
void
|
|
store(value_type const& v, memory_order order = memory_order_seq_cst) ) volatile BOOST_NOEXCEPT
|
|
{
|
|
storage_type tmp = 0;
|
|
memcpy(&tmp, &v, sizeof(value_type));
|
|
platform_fence_before_store(order);
|
|
const_cast<volatile storage_type &>(v_) = tmp;
|
|
platform_fence_after_store(order);
|
|
}
|
|
|
|
value_type
|
|
load(memory_order order = memory_order_seq_cst) const volatile
|
|
{
|
|
storage_type tmp = const_cast<const volatile storage_type &>(v_);
|
|
platform_fence_after_load(order);
|
|
|
|
value_type v;
|
|
memcpy(&v, &tmp, sizeof(value_type));
|
|
return v;
|
|
}
|
|
|
|
value_type
|
|
exchange(value_type const& v, memory_order order = memory_order_seq_cst) ) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
bool
|
|
compare_exchange_weak(
|
|
value_type & expected,
|
|
value_type const& desired,
|
|
memory_order success_order,
|
|
memory_order failure_order) ) volatile BOOST_NOEXCEPT
|
|
{
|
|
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
|
}
|
|
|
|
bool
|
|
compare_exchange_strong(
|
|
value_type & expected,
|
|
value_type const& desired,
|
|
memory_order success_order,
|
|
memory_order failure_order) ) volatile BOOST_NOEXCEPT
|
|
{
|
|
storage_type expected_s = 0, desired_s = 0;
|
|
memcpy(&expected_s, &expected, sizeof(value_type));
|
|
memcpy(&desired_s, &desired, sizeof(value_type));
|
|
|
|
platform_fence_before(success_order);
|
|
bool success = platform_cmpxchg32_strong(expected_s, desired_s, &v_);
|
|
|
|
if (success) {
|
|
platform_fence_after(success_order);
|
|
} else {
|
|
platform_fence_after(failure_order);
|
|
memcpy(&expected, &expected_s, sizeof(value_type));
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
bool
|
|
is_lock_free(void) const volatile
|
|
{
|
|
return true;
|
|
}
|
|
|
|
BOOST_ATOMIC_DECLARE_BASE_OPERATORS
|
|
private:
|
|
base_atomic(const base_atomic &) /* = delete */ ;
|
|
void operator=(const base_atomic &) /* = delete */ ;
|
|
storage_type v_;
|
|
};
|
|
|
|
template<typename T, bool Sign>
|
|
class base_atomic<T, void, 2, Sign>
|
|
{
|
|
typedef base_atomic this_type;
|
|
typedef T value_type;
|
|
typedef uint32_t storage_type;
|
|
public:
|
|
explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
|
|
{
|
|
memcpy(&v_, &v, sizeof(value_type));
|
|
}
|
|
|
|
base_atomic(void) {}
|
|
|
|
void
|
|
store(value_type const& v, memory_order order = memory_order_seq_cst) ) volatile BOOST_NOEXCEPT
|
|
{
|
|
storage_type tmp = 0;
|
|
memcpy(&tmp, &v, sizeof(value_type));
|
|
platform_fence_before_store(order);
|
|
const_cast<volatile storage_type &>(v_) = tmp;
|
|
platform_fence_after_store(order);
|
|
}
|
|
|
|
value_type
|
|
load(memory_order order = memory_order_seq_cst) const volatile
|
|
{
|
|
storage_type tmp = const_cast<const volatile storage_type &>(v_);
|
|
platform_fence_after_load(order);
|
|
|
|
value_type v;
|
|
memcpy(&v, &tmp, sizeof(value_type));
|
|
return v;
|
|
}
|
|
|
|
value_type
|
|
exchange(value_type const& v, memory_order order = memory_order_seq_cst) ) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
bool
|
|
compare_exchange_weak(
|
|
value_type & expected,
|
|
value_type const& desired,
|
|
memory_order success_order,
|
|
memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
{
|
|
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
|
}
|
|
|
|
bool
|
|
compare_exchange_strong(
|
|
value_type & expected,
|
|
value_type const& desired,
|
|
memory_order success_order,
|
|
memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
{
|
|
|
|
storage_type expected_s = 0, desired_s = 0;
|
|
memcpy(&expected_s, &expected, sizeof(value_type));
|
|
memcpy(&desired_s, &desired, sizeof(value_type));
|
|
|
|
platform_fence_before(success_order);
|
|
bool success = platform_cmpxchg32_strong(expected_s, desired_s, &v_);
|
|
|
|
if (success) {
|
|
platform_fence_after(success_order);
|
|
} else {
|
|
platform_fence_after(failure_order);
|
|
memcpy(&expected, &expected_s, sizeof(value_type));
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
bool
|
|
is_lock_free(void) const volatile
|
|
{
|
|
return true;
|
|
}
|
|
|
|
BOOST_ATOMIC_DECLARE_BASE_OPERATORS
|
|
private:
|
|
base_atomic(const base_atomic &) /* = delete */ ;
|
|
void operator=(const base_atomic &) /* = delete */ ;
|
|
storage_type v_;
|
|
};
|
|
|
|
template<typename T, bool Sign>
|
|
class base_atomic<T, void, 4, Sign>
|
|
{
|
|
typedef base_atomic this_type;
|
|
typedef T value_type;
|
|
typedef uint32_t storage_type;
|
|
public:
|
|
explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
|
|
{
|
|
memcpy(&v_, &v, sizeof(value_type));
|
|
}
|
|
|
|
base_atomic(void) {}
|
|
|
|
void
|
|
store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
storage_type tmp = 0;
|
|
memcpy(&tmp, &v, sizeof(value_type));
|
|
platform_fence_before_store(order);
|
|
const_cast<volatile storage_type &>(v_) = tmp;
|
|
platform_fence_after_store(order);
|
|
}
|
|
|
|
value_type
|
|
load(memory_order order = memory_order_seq_cst) const volatile
|
|
{
|
|
storage_type tmp = const_cast<const volatile storage_type &>(v_);
|
|
platform_fence_after_load(order);
|
|
|
|
value_type v;
|
|
memcpy(&v, &tmp, sizeof(value_type));
|
|
return v;
|
|
}
|
|
|
|
value_type
|
|
exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
|
{
|
|
value_type original = load(memory_order_relaxed);
|
|
do {
|
|
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
|
|
return original;
|
|
}
|
|
|
|
bool
|
|
compare_exchange_weak(
|
|
value_type & expected,
|
|
value_type const& desired,
|
|
memory_order success_order,
|
|
memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
{
|
|
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
|
}
|
|
|
|
bool
|
|
compare_exchange_strong(
|
|
value_type & expected,
|
|
value_type const& desired,
|
|
memory_order success_order,
|
|
memory_order failure_order) volatile BOOST_NOEXCEPT
|
|
{
|
|
|
|
storage_type expected_s = 0, desired_s = 0;
|
|
memcpy(&expected_s, &expected, sizeof(value_type));
|
|
memcpy(&desired_s, &desired, sizeof(value_type));
|
|
|
|
platform_fence_before(success_order);
|
|
bool success = platform_cmpxchg32_strong(expected_s, desired_s, &v_);
|
|
|
|
if (success) {
|
|
platform_fence_after(success_order);
|
|
} else {
|
|
platform_fence_after(failure_order);
|
|
memcpy(&expected, &expected_s, sizeof(value_type));
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
bool
|
|
is_lock_free(void) const volatile
|
|
{
|
|
return true;
|
|
}
|
|
|
|
BOOST_ATOMIC_DECLARE_BASE_OPERATORS
|
|
private:
|
|
base_atomic(const base_atomic &) /* = delete */ ;
|
|
void operator=(const base_atomic &) /* = delete */ ;
|
|
storage_type v_;
|
|
};
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|